Codeforces Round #149 (Div. 2)

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 }
posted @ 2012-11-13 13:25  發_  阅读(262)  评论(0编辑  收藏  举报