B:
二分图的染色应用。
首先,注意题目的信息。
每个人最多有三个认识的人。
那么,我们可以思考,当有三个人和一个人连边时。
如果有两个人和他同色,一个人不同色。
那么将这个人反转,就变成了,一个人和他同色,两个人不同色。
那么可以发现,对于每一个人,翻转后可以减少同色的数量。
可以证明,必定存在解。即存在排列,分散两堆人。
思路:
先对每个没有染色过的点染色,当一个点和它相邻的点的同色点>=2时,就翻转它的颜色。
注意的是,对于一个没有染色过的点,染色过后也需要判断是否和u同色。
因为这个v点可能在dfs下层被翻转.
Code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e5+5; const int M = 1e6+5; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e18 #define INM INT_MIN #define rg register #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) struct Node{int next,to;}e[N<<1]; int cnt = 0,head[N],col[N]; inline void add(int u,int v) { e[++cnt].to = v,e[cnt].next = head[u],head[u] = cnt; } void dfs(int u,int c) { col[u] = c; int ma = 0; for(int i = head[u];i;i = e[i].next) { int v = e[i].to; if(col[v] == 0) dfs(v,c^3); if(col[v] == col[u]) ma++; } if(ma >= 2) col[u] ^= 3; } void run() { int n,m;sdd(n,m); while(m--) { int u,v;sdd(u,v); add(u,v);add(v,u); } for(int i = 1;i <= n;++i) if(col[i] == 0) dfs(i,1); for(int i = 1;i <= n;++i) printf("%d%c",col[i],i == n ? '\n' : ' '); } int main() { run(); system("pause"); return 0; }
D:
博弈论。
发现,对于每次变换,左上角的(1,1)始终都会变换。
对于结果,肯定是所有都为B。
所有对于左上角,肯定是最终变为B。
然后R-G-B三色变换,正好是一个周期。
所以每次经过一个周期变换,相当于没有操作。
所以只需要判断(1,1)一开始的状态即可。
Code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e5+5; const int M = 1e6+5; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e18 #define INM INT_MIN #define rg register #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) string mp[1005]; void run() { int t;sd(t); while(t--) { int n,m;sdd(n,m); for(int i = 0;i < n;++i) cin >> mp[i]; if(mp[0][0] == 'G') printf("fengxunling\n"); else if(mp[0][0] == 'R')printf("dreagonm\n"); else printf("BLUESKY007\n"); } } int main() { run(); system("pause"); return 0; }
C:
线段树维护一下二进制位的1即可。
注意0应该用num-1来,记0的个数会记空的位置.
Code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5+5; const int M = 1e6+5; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e18 #define INM INT_MIN #define rg register #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) struct Node { int L,r; LL sum = 0,tag = 0,cnt[25]; }node[N<<2]; LL a[N]; void Pushup(int idx) { node[idx].sum = node[idx<<1].sum + node[idx<<1|1].sum; for(int i = 0;i < 25;++i) { node[idx].cnt[i] = node[idx<<1].cnt[i]+node[idx<<1|1].cnt[i]; } } void Pushdown(int idx) { if(node[idx].tag != 0) { int tag = node[idx].tag; int num1 = (node[idx<<1].r-node[idx<<1].L+1); int num2 = (node[idx<<1|1].r-node[idx<<1|1].L+1); for(int i = 0;i < 25;++i) { int t = (tag>>i)&1; int a1 = node[idx<<1].cnt[i]; int b1 = node[idx<<1|1].cnt[i]; if(t == 1) { node[idx<<1].sum += (1<<i)*(num1-a1); node[idx<<1].sum -= (1<<i)*a1; node[idx<<1|1].sum += (1<<i)*(num2-b1); node[idx<<1|1].sum -= (1<<i)*b1; node[idx<<1].cnt[i] = num1-a1; node[idx<<1|1].cnt[i] = num2-b1; } } node[idx<<1].tag ^= tag; node[idx<<1|1].tag ^= tag; node[idx].tag = 0; } } void build(int L,int r,int idx) { node[idx].L = L,node[idx].r = r; if(L == r) { node[idx].sum = a[L]; for(int i = 0;i < 25;++i) { int t = (a[L]>>i)&1; if(t == 1) node[idx].cnt[i]++; } // for(int i = 0;i < 25;++i) printf("i is %d cnt is %d\n",i,node[idx].cnt[i]); return ; } int mid = (node[idx].L+node[idx].r)>>1; build(L,mid,idx<<1); build(mid+1,r,idx<<1|1); Pushup(idx); } void update(int L,int r,int idx,int k) { if(node[idx].L >= L && node[idx].r <= r) { int num = (node[idx].r-node[idx].L+1); for(int i = 0;i < 25;++i) { int t = (k>>i)&1; int a1 = node[idx].cnt[i]; if(t == 1) { node[idx].sum += (1<<i)*(num-a1); node[idx].sum -= (1<<i)*a1; node[idx].cnt[i] = num-a1; // printf("i is %d a1 is %d sum is %d\n",i,a1,node[idx].sum); } } node[idx].tag ^= k; } else { Pushdown(idx); int mid = (node[idx].L+node[idx].r)>>1; if(mid >= L) update(L,r,idx<<1,k); if(mid < r) update(L,r,idx<<1|1,k); Pushup(idx); } } LL query(int L,int r,int idx) { if(node[idx].L >= L && node[idx].r <= r) return node[idx].sum; int mid = (node[idx].L+node[idx].r)>>1; LL ans = 0; Pushdown(idx); if(mid >= L) ans += query(L,r,idx<<1); if(mid < r) ans += query(L,r,idx<<1|1); return ans; } void run() { int n,m;sdd(n,m); for(int i = 1;i <= n;++i) sld(a[i]); build(1,n,1); while(m--) { int id;sd(id); if(id == 1) { int L,r;sdd(L,r); LL ans = query(L,r,1); plr(ans); } if(id == 2) { int L,r,k;sddd(L,r,k); update(L,r,1,k); } } } int main() { run(); // system("pause"); return 0; }