• 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 }
  • 相关阅读:
    hdu 5517 Triple(二维树状数组)
    bzoj 3998: [TJOI2015]弦论(后缀自动机)
    hdu 5008 Boring String Problem(后缀数组+rmq)
    hdu 4622 Reincarnation(后缀自动机)
    hdu 6025 card card card(双指针)
    寒武纪camp Day3
    寒武纪camp Day2
    寒武纪camp Day1
    Codeforces 920G(二分+容斥)
    Codeforces 920E(补图BFS)
  • 原文地址:https://www.cnblogs.com/fzf123/p/2767142.html
Copyright © 2020-2023  润新知