机房测试:Dove打扑克(vector暴力)

题目:

 

 题目:

我怎么也不会想到,这道题的正解会如此的暴力。。。

一开始我的做法是开一个桶记录一下每种元素的出现次数,每次查找的时候,枚举一个元素x,查询大于等于x+c的个数。

这样是n*m的,但是其实不同的元素个数只有sqrt(n)个,因为:1+2+3+……x=n,x最多为sqrt(n)

所以用一个vector或者set记录一下目前有值的元素是哪些,每一次只for那些即可。

查询的时候用树状数组维护即可。

复杂度:O(m*sqrt(n)*logn)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ri register int
#define N 100005
int tong[N],cnt[N],sum[N],fa[N],n,m,t[N*4];
set<int> st;
int read()
{
    int x=0,fl=1; char ch=getchar();
    while(ch<'0' || ch>'9') { if(ch=='-') fl=-1; ch=getchar(); }
    while(ch<='9' && ch>='0') x=x*10+ch-'0',ch=getchar();
    return x*fl;
}
int find(int x) { if(x==fa[x]) return x; return fa[x]=find(fa[x]); }
void modify(int x,int v)
{
    while(x<=n) { t[x]+=v; x+=(x&-x); }
}
ll query(int x)
{
    ll ans=0;
    while(x>0) { ans+=t[x]; x-=(x&-x); }
    return ans;
}
ll work(int c)
{
    ll ans=0;
    if(c==0){
        ll x=query(n);
        return x*(x-1)/2;
    }
    set<int>::iterator it=st.begin();//set保证插入的元素都是有序的 
    for(it;it!=st.end();++it){
        int tp=*it;//这样就可以遍历每一个元素 
        if(tp+c>n) break;
        ll x=query(n)-query(tp+c-1);
        ans+=1ll*x*tong[tp];
    }
    return ans;
}
int main()
{
    freopen("cards.in","r",stdin);
    freopen("cards.out","w",stdout);
    n=read(); m=read();
    for(ri i=1;i<=n;++i) fa[i]=i,cnt[i]=1;
    tong[1]=n; modify(1,n); st.insert(1);
    while(m--){
        int op=read();
        if(op==1){
            int x=read(), y=read();
            int f1=find(x),f2=find(y);
            if(f1==f2) continue;
            tong[cnt[f2]]--; tong[cnt[f1]]--;
            modify(cnt[f2],-1); modify(cnt[f1],-1);
            if(!tong[cnt[f2]]) st.erase(cnt[f2]);
            if(!tong[cnt[f1]]) st.erase(cnt[f1]);
            cnt[f2]+=cnt[f1];
            if(!tong[cnt[f2]]) st.insert(cnt[f2]);
            modify(cnt[f2],1);
            tong[cnt[f2]]++;
            fa[f1]=f2;
            cnt[f1]=-1;
        }
        else{
            int c=read();
            printf("%lld
",work(c));
        }
    }
    return 0;
}
/*
7 5
2 1
1 4 1
2 3
2 1
2 0
*/
View Code
原文地址:https://www.cnblogs.com/mowanying/p/11822893.html