Codeforces Round #439 (Div. 2)

A题

分析:注意异或以后可能会大于2e6,所以数组应该开到4e6。还有一种巧妙的解法就是用异或的性质,b^a^b=a,所以可以看出必然都是偶数对。

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "string"
 5 #include "cmath"
 6 #include "vector"
 7 using namespace std;
 8 const int maxn=5000;
 9 const int maxm=4e6+10;
10 int x[maxn],y[maxn];
11 int vis[maxm];
12 int n;
13 //vector<int> res;
14 int main()
15 {
16     scanf("%d",&n);
17     //res.push_back(0);
18     for(int i=1;i<=n;i++){
19         scanf("%d",&x[i]);
20         vis[x[i]]=1;
21         //res.push_back(x[i]);
22     }
23     for(int i=1;i<=n;i++){
24         scanf("%d",&y[i]);
25         vis[y[i]]=1;
26         //res.push_back(y[i]);
27     }
28     int cnt=0;
29     for(int i=1;i<=n;i++){
30         for(int j=1;j<=n;j++){
31             int num=x[i]^y[j];
32             if(vis[num]){
33                 cnt++;
34                 //cout<<res[i]<<" "<<res[j]<<endl;
35                 //cout<<num<<endl;
36             }
37         }
38     }
39     //cout<<(1^1)<<endl;
40     //cout<<cnt<<endl;
41     if(cnt%2==0)
42         cout<<"Karen"<<endl;
43     else
44         cout<<"Koyomi"<<endl;
45 }
View Code

B题

分析:要求最后一位数分为几种情况,如果两数之差超过10的,因为最后一位出现0,所以必然为0。如果两数相等,直接对10曲余,否则直接暴力即可。

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "string"
 5 #include "vector"
 6 using namespace std;
 7 long long a,b;
 8 int main()
 9 {
10     cin>>a>>b;
11     if(b-a>=10){
12         cout<<"0"<<endl;
13     }else{
14         long long t=b-a;
15         if(t==0)
16             cout<<"1"<<endl;
17         else if(t==1){
18             cout<<b%10<<endl;
19         }
20         else{
21             long long z=1;
22             vector<int>t;
23             for(long long i=a+1;i<=b;i++){
24                 int num=i%10;
25                 t.push_back(num);
26             }
27             for(int i=0;i<t.size();i++)
28                 z*=t[i];
29             z=z%10;
30             cout<<z<<endl;
31         }
32     }
33 }
View Code

C题

分析:题意比较难理解,就是给定三个集合,每个集合的元素个数分别为a,b,c。然后相同的一个集合当中任何两元素之间最短路必须大于等于3。求最多有多少种连线方式。根据题意我们就可以得知,首先同色的不可能相连,同时两个同色的不能连在一个其他颜色上。这个结论太重要了,这就说明了我们连任意两种颜色是独立的,于是最后结果就是(a,b),(a,c),(b,c)三者的乘积。而对于选取任意两种颜色,假设(a<b),那我们如果选取k条线段的话,必然有C(a,k)*C(b,k)*k!种组合方式,所以最终结果也就是k从0取到a的和,然后其余颜色也依次类推。

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "string"
 5 #include "cmath"
 6 #include "algorithm"
 7 using namespace std;
 8 typedef long long LL;
 9 const LL mod= 998244353;
10 const int maxn=5050;
11 LL a[10];
12 LL f[maxn],dp[maxn][maxn];
13 void init(int n){
14     f[0]=1;
15     for(int i=1;i<=n;i++){
16         f[i]=f[i-1]*i;
17         f[i]%=mod;
18     }
19     for(int i=0;i<=n;i++){
20         dp[i][0]=1;
21     }
22     for(int i=1;i<=n;i++){
23         for(int j=1;j<=i;j++){
24             dp[i][j]=(dp[i-1][j-1]%mod+(dp[i-1][j]%mod))%mod;
25         }
26     }
27 }
28 int main()
29 {
30     cin>>a[1]>>a[2]>>a[3];
31     sort(a+1,a+4);
32     init(5000);
33     LL num1=0,num2=0,num3=0;
34     for(int i=0;i<=a[1];i++){
35         num1+=((dp[a[1]][i]%mod*(dp[a[2]][i]%mod))%mod*f[i])%mod;
36         num1%=mod;
37     }
38     for(int i=0;i<=a[2];i++){
39         num2+=((dp[a[2]][i]%mod*(dp[a[3]][i]%mod))%mod*f[i])%mod;
40         num2%=mod;
41     }
42     for(int i=0;i<=a[1];i++){
43         num3+=((dp[a[1]][i]%mod*(dp[a[3]][i]%mod))%mod*f[i])%mod;
44         num3%=mod;
45     }
46     LL ans=((num1*num2)%mod*num3)%mod;
47     cout<<ans<<endl;
48 }
View Code

 E题

分析:围墙之间不相交,所以我们可以把每个围墙内部都设置成一个值,询问的时候只要看两个点的值是否相同即可。那么怎么

将一个围墙内设为一个值呢,我们可以利用二维BIT,利用前缀和,进行区间更新,单点查询,跟一维的时候区间更新单点更新一

样。那么删除的时候怎么快速得到这个围墙原来设置的是什么值呢,我们可以用哈希,将四个坐标哈希成一个值。

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "string"
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn=2500+10;
 8 const LL val=2333;
 9 LL c[maxn][maxn];
10 int n,m,q;
11 int lowbit(int x){
12     return x&(-x);
13 }
14 void add(int x,int y,LL k){
15     for(int i=x;i<=n;i+=lowbit(i))
16         for(int j=y;j<=m;j+=lowbit(j))
17             c[i][j]+=k;
18 }
19 void update(int x1,int y1,int x2,int y2,LL k){
20     add(x2+1,y2+1,k);
21     add(x2+1,y1,-k);
22     add(x1,y2+1,-k);
23     add(x1,y1,k);
24 }
25 LL sum(int x,int y){
26     LL ans=0;
27     for(int i=x;i;i-=lowbit(i))
28         for(int j=y;j;j-=lowbit(j))
29             ans+=c[i][j];
30     return ans;
31 }
32 int main()
33 {
34     scanf("%d%d%d",&n,&m,&q);
35     for(int cas=1;cas<=q;cas++){
36         int num,x1,y1,x2,y2;
37         scanf("%d%d%d%d%d",&num,&x1,&y1,&x2,&y2);
38         LL ans=x1;
39         ans=ans*val+y1;
40         ans=ans*val+x2;
41         ans=ans*val+y2;
42         if(num==1)
43             update(x1,y1,x2,y2,ans);
44         else if(num==2)
45             update(x1,y1,x2,y2,-ans);
46         else{
47             LL ans1=sum(x1,y1);
48             LL ans2=sum(x2,y2);
49             if(ans1==ans2)
50                 cout<<"Yes"<<endl;
51             else
52                 cout<<"No"<<endl;
53         }
54     }
55 }
View Code
原文地址:https://www.cnblogs.com/wolf940509/p/7636291.html