http://codeforces.com/contest/242
C题:给出一些线段,起点和终点,只能在线段上走,线段范围上限为1e9,但是线段的总长不超过1e5.
做法:bfs+map
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <sstream> 8 #include <iostream> 9 #include <cmath> 10 #include <cstring> 11 #include <algorithm> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 #include <queue> 16 #include <stack> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define REP(i,n) for(int i=0;i < (n);i++) 24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 25 #define PII pair<int,int> 26 #define PB push_back 27 #define MP make_pair 28 #define ft first 29 #define sd second 30 #define lowbit(x) (x&(-x)) 31 #define INF (1<<30) 32 33 PII point; 34 map<PII,int> S,S1; 35 int X0,Y0,X1,Y1; 36 int bfs(void) 37 { 38 S1.clear(); 39 queue<PII> Q; 40 Q.push(MP(X0,Y0)); 41 S[MP(X0,Y0)] = 0; 42 while(!Q.empty()) 43 { 44 int xx = Q.front().ft; 45 int yy = Q.front().sd; 46 Q.pop(); 47 FOR(i,-1,1)FOR(j,-1,1) 48 { 49 if(!i && !j)continue; 50 PII next = MP(xx + i,yy + j); 51 if(!S.count(next) || S1.count(next))continue; 52 Q.push(next); 53 S1[next] = S1[MP(xx,yy)] + 1; 54 if(next.ft == X1 && next.sd == Y1)return S1[next]; 55 } 56 } 57 return -1; 58 } 59 int main() 60 { 61 //freopen("in","r",stdin); 62 while(cin>>X0>>Y0>>X1>>Y1) 63 { 64 int n; 65 cin>>n; 66 int r,a,b; 67 S.clear(); 68 REP(i,n) 69 { 70 cin>>r>>a>>b; 71 FOR(i,a,b) 72 { 73 S[MP(r,i)]++; 74 } 75 } 76 printf("%d\n",bfs()); 77 } 78 return 0; 79 }
D题:每一个节点press一次就会+1,其相邻节点也会+1,每一个节点只能press一次,初始每个节点bi都为0,问press哪些节点
使得最后bi != ai。
做法:如果bi == ai就press,可以用bfs直到所有bi != ai。因为bi只会增加,所以一定有解,复杂度为O(n)。
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <sstream> 8 #include <iostream> 9 #include <cmath> 10 #include <cstring> 11 #include <algorithm> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 #include <queue> 16 #include <stack> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define REP(i,n) for(int i=0;i < (n);i++) 24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 25 #define PII pair<int,int> 26 #define PB push_back 27 #define MP make_pair 28 #define FI first 29 #define SE second 30 #define lowbit(x) (x&(-x)) 31 #define INF (1<<30) 32 33 vector<int> vec[100005]; 34 int X[100005]; 35 int a[100005],b[100005]; 36 int main() 37 { 38 //freopen("in","r",stdin); 39 int n,m; 40 while(cin>>n>>m) 41 { 42 queue<int> Q; 43 int k = 0; 44 memset(b,0,sizeof(b)); 45 while(m --) 46 { 47 int u,v; 48 cin>>u>>v; 49 vec[u].PB(v); 50 vec[v].PB(u); 51 } 52 FOR(i,1,n) 53 { 54 cin>>a[i]; 55 if(a[i] == 0) 56 { 57 Q.push(i);b[i]++;X[k++]=i; 58 REP(j,vec[i].size())b[vec[i][j]] ++; 59 } 60 } 61 while(!Q.empty()) 62 { 63 int x = Q.front();Q.pop(); 64 REP(i,vec[x].size()) 65 { 66 int v = vec[x][i]; 67 //DEBUG(v); 68 //DEBUG(a[v]);DEBUG(b[v]); 69 if(b[v] == a[v]) 70 { 71 Q.push(v); 72 b[v] ++; 73 X[k++] = v; 74 REP(j,vec[v].size())b[vec[v][j]]++; 75 } 76 } 77 } 78 printf("%d\n",k); 79 REP(i,k)printf("%d ",X[i]); 80 puts(""); 81 } 82 return 0; 83 }
E题不错
1)区间求和。
2)区间更新,每个数异或X。
做法:把每个数按二进制拆位,故可以建20棵线段树。
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <sstream> 8 #include <iostream> 9 #include <cmath> 10 #include <cstring> 11 #include <algorithm> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 #include <queue> 16 #include <stack> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define REP(i,n) for(int i=0;i < (n);i++) 24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 25 #define PII pair<int,int> 26 #define PB push_back 27 #define MP make_pair 28 #define FI first 29 #define SE second 30 #define lowbit(x) (x&(-x)) 31 #define INF (1<<30) 32 33 #define lson l , m , rt<<1 34 #define rson m + 1 , r , rt<<1|1 35 36 const int maxn = 100111; 37 int col[maxn<<2]; 38 ll sum[maxn<<2][22]; 39 40 void PushUp(int rt) 41 { 42 REP(i,21) 43 sum[rt][i] = sum[rt<<1][i] + sum[rt<<1|1][i]; 44 } 45 void PushDown(int rt,int m) 46 { 47 if(col[rt]) 48 { 49 col[rt<<1] ^= col[rt]; 50 col[rt<<1|1] ^= col[rt]; 51 REP(i,21) 52 { 53 if(col[rt]&1) 54 { 55 sum[rt<<1][i] = m - (m>>1) - sum[rt<<1][i]; 56 sum[rt<<1|1][i] = (m>>1) - sum[rt<<1|1][i]; 57 } 58 col[rt] >>= 1; 59 } 60 } 61 } 62 void build(int l,int r,int rt) 63 { 64 REP(i,21)sum[rt][i] = 0; 65 col[rt] = 0; 66 if(l == r) 67 { 68 int A; 69 scanf("%I64d",&A); 70 REP(i,21) 71 { 72 sum[rt][i] = (A&1); 73 A >>= 1; 74 } 75 return ; 76 } 77 int m = (l + r) >> 1; 78 build(lson); 79 build(rson); 80 PushUp(rt); 81 } 82 void updata(int L,int R,int X,int l,int r,int rt) 83 { 84 if(L <= l && r <= R) 85 { 86 col[rt] ^= X; 87 REP(i,21) 88 { 89 if(X&1)sum[rt][i] = r - l + 1 - sum[rt][i];//0变1,1变0 90 X>>=1; 91 } 92 return ; 93 } 94 PushDown(rt,r-l+1); 95 int m = (l + r) >> 1; 96 if(L <= m)updata(L,R,X,lson); 97 if(m < R)updata(L,R,X,rson); 98 PushUp(rt); 99 } 100 ll query(int L,int R,int l,int r,int rt) 101 { 102 if(L <= l && r <= R) 103 { 104 ll tmp = 0; 105 REP(i,21) 106 { 107 tmp += sum[rt][i]*(1LL<<i); 108 } 109 return tmp; 110 } 111 PushDown(rt,r-l+1); 112 int m = (l + r) >> 1; 113 ll ret = 0; 114 if(L <= m)ret += query(L,R,lson); 115 if(m < R)ret += query(L,R,rson); 116 return ret; 117 } 118 int main() 119 { 120 //freopen("in","r",stdin); 121 int n; 122 while(~scanf("%d",&n)) 123 { 124 build(1,n,1); 125 int m; 126 scanf("%d",&m); 127 int op,l,r,x; 128 while(m--) 129 { 130 scanf("%d",&op); 131 if(op == 1) 132 { 133 scanf("%d%d",&l,&r); 134 printf("%I64d\n",query(l,r,1,n,1)); 135 } 136 else 137 { 138 scanf("%d%d%d",&l,&r,&x); 139 updata(l,r,x,1,n,1); 140 } 141 } 142 } 143 return 0; 144 }