【BestCoder】【Round#44】

模拟+Trie+桶排(归并?)+容斥


 

A

  模(shou)拟(su)题= =感觉好像见过?

  计算得分什么的……

 1 //BestCoder #44 A
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 inline int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
17     return v*sign;
18 }
19 const int N=1e5+10,INF=~0u>>2;
20 typedef long long LL;
21 /******************tamplate*********************/
22 const int b[]={0,1000,1500,2000,2500};
23 
24 int main(){
25     int T=getint();
26     F(CS,1,T){
27         int ans=0;
28         F(i,1,4){
29             int x=getint(),y=getint();
30             ans+=max(b[i]*0.4,(b[i]*(250.0-x)/250.0)-y*50);
31         }
32         printf("Case #%d: %d\n",CS,ans);
33     }
34     return 0;
35 }
View Code

B

  给一个数组$A_i$,问$\sum_{i,j} lowbit(A_i \otimes A_j)$等于?

  Trie树随便搞搞= =,因为从Trie上从上往下走到节点x,这个节点代表的子树中的所有数,它们的前缀是相同的(从二进制角度来看,后面xxx位都是相同的),所以前缀的异或为0,左子树中的数与右子树中的数的异或值的lowbit即为(1<<dep),dep即为当前点的深度。。。

  所以遍历一遍整个Trie就可以算出来答案了= =

  就是要注意一下,如果后缀都是0(从二进制角度来看是靠前的位),也要在Trie中补齐

 1 //BestCoder #44 B
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 inline int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
17     return v*sign;
18 }
19 const int N=5e6+10,INF=~0u>>2,P=998244353;
20 typedef long long LL;
21 /******************tamplate*********************/
22 
23 int c[N][2],size[N],tot;
24 int n,m,a[N],ans;
25 
26 void Insert(int v){
27     int x=1;
28     F(i,0,30){
29         int j=v&1;
30         if (!c[x][j]) c[x][j]=++tot;
31         size[x]++;
32         x=c[x][j]; v>>=1;
33     }
34     size[x]++;
35 }
36 void dp(int x,int len){
37     if (!x||size[x]==1) return;
38 //    printf("dp %d %d  ",x,len);
39 //    printf("size[L]=%d size[R]=%d\n",size[c[x][0]],size[c[x][1]]);
40     ans=((LL)ans+(LL)size[c[x][0]]*size[c[x][1]]%P*(1<<len)%P)%P;
41     dp(c[x][0],len+1); dp(c[x][1],len+1);
42 }
43 int main(){
44 #ifndef ONLINE_JUDGE
45     freopen("B.in","r",stdin);
46     freopen("B.out","w",stdout);
47 #endif
48     int T=getint();
49     F(cs,1,T){
50         printf("Case #%d: ",cs);
51         n=getint();
52         memset(c,0,sizeof c); tot=1;
53         memset(size,0,sizeof size);
54         F(i,1,n){
55             a[i]=getint();
56             Insert(a[i]);
57         }
58         ans=0;
59         dp(1,0);
60         printf("%d\n",(ans*2)%P);
61 /*        ans=0;
62         F(i,1,n) F(j,1,n){
63             int tmp=a[i]^a[j];
64             ans+=tmp&(-tmp);
65         }
66         printf("%d\n",ans);
67 */    }
68     return 0;
69 }
View Code

C

  这个题其实我不会做= =

  我yy的方法是:对A数组建出一棵Trie,然后对于每一个在B中的数,从Trie上往下走,向0走的时候b[i]>>=1,向1走的时候b[i]=(b[i]+1>>1)(执行加法)

  然而这样是$O(n^2*log^2n)$的……这样做还不如暴力2333

  膜了jiry_2老司机的代码,原来是从高位到低位依次计算,桶排一下,将这一位是0的放到一起,是1的放到一起……然后利用一下容斥原理&单调性,搞出和中这一位是1的数量,异或一下。。。

 1 //BestCoder #44 C
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 typedef long long LL;
14 inline LL getint(){
15     LL v=0,sign=1; char ch=getchar();
16     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
17     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
18     return v*sign;
19 }
20 const int N=1e5+10,INF=~0u>>2;
21 /******************tamplate*********************/
22 
23 int n,tot;
24 vector<LL>A[2];
25 LL x[N],y[N];
26 int main(){
27 #ifndef ONLINE_JUDGE
28     freopen("C.in","r",stdin);
29     freopen("C.out","w",stdout);
30 #endif
31     int T=getint();
32     F(cs,1,T){
33         printf("Case #%d: ",cs);
34         n=getint();
35         F(i,1,n) x[i]=getint();
36         F(i,1,n) y[i]=getint();
37         LL num=0;
38         F(now,0,61){
39             A[0].clear(); A[1].clear();
40             F(i,1,n) A[x[i]>>now&1].pb(x[i]);
41             int head=0;
42             rep(i,A[0].size()) x[++head]=A[0][i];
43             rep(i,A[1].size()) x[++head]=A[1][i];
44             A[0].clear(); A[1].clear();
45             F(i,1,n) A[y[i]>>now&1].pb(y[i]);
46             head=0;
47             rep(i,A[0].size()) y[++head]=A[0][i];
48             rep(i,A[1].size()) y[++head]=A[1][i];
49             LL tot=(1LL<<(now+1))-1,lim=1LL<<now,lim2=(1LL<<now+1),ans=0;
50             int a=0,b=0,c=0;
51             D(i,n,1){
52                 while(a<n && (x[i]&tot)+(y[a+1]&tot)<lim)a++;
53                 while(b<n && (x[i]&tot)+(y[b+1]&tot)<lim2)b++;
54                 while(c<n && (x[i]&tot)+(y[c+1]&tot)<lim+lim2)c++;
55                 ans+=n-c+b-a;
56             }
57             if (ans&1) num|=(1LL<<now);
58         }
59         printf("%lld\n",num);
60     }
61     return 0;
62 }
View Code

 

posted @ 2015-06-15 08:31  Tunix  阅读(218)  评论(0编辑  收藏  举报