zoukankan      html  css  js  c++  java
  • 15.3.22湖南省多校对抗

    http://acm.csu.edu.cn/OnlineJudge/contest.php?cid=2070

    比赛是组队赛,居然弄了一个第三名,现场第二,醉了

    多亏队友们的齐心协力,全部1A,出的题不是最多但是比较快没有罚时~

    赛后自己把题目又重新A了一遍。

    A:CSU1536N比较小,直接暴力搜索一遍

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FIN freopen("in.txt", "r", stdin)
    23 #define FOUT freopen("out.txt", "w", stdout)
    24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
    25  
    26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    32  
    33 //typedef __int64 LL;
    34 typedef long long LL;
    35 const int MAXN = 1010;
    36 const int MAXM = 2000010;
    37 const double eps = 1e-4;
    38  
    39 int n, m;
    40 struct Node {
    41     int arr[16], step;
    42 }s;
    43 int tar[20], vis[1 << 16];
    44  
    45 int conv(Node a) {
    46     int ret = 0;
    47     rep (i, 0, n - 1) {
    48         ret <<= 1;
    49         ret |= a.arr[i];
    50     }
    51     return ret;
    52 }
    53  
    54 int getEnd(Node a) {
    55     int cnt = 1, id = 0;
    56     rep (i, 1, n - 1) {
    57         if(a.arr[i] == a.arr[i - 1]) cnt ++;
    58         else {
    59             if(cnt != tar[id]) return 0;
    60             cnt = 1; id ++;
    61         }
    62     }
    63     return cnt == tar[id];
    64 }
    65  
    66 int bfs()
    67 {
    68     mem0(vis);
    69     queue<Node>q;
    70     s.step = 0;
    71     vis[conv(s)] = 1;
    72     q.push(s);
    73     while(!q.empty()) {
    74         Node fr = q.front(); q.pop();
    75         if(getEnd(fr)) return fr.step;
    76         rep (i, 0, n - 2) {
    77             Node tail = fr;
    78             swap(tail.arr[i], tail.arr[i + 1]);
    79             if(!vis[conv(tail)]) {
    80                 tail.step = fr.step + 1;
    81                 q.push(tail);
    82                 vis[conv(tail)] = 1;
    83             }
    84         }
    85     }
    86     return 0;
    87 }
    88  
    89 int main()
    90 {
    91     //FIN;
    92     while(~scanf("%d %d", &n, &m)) {
    93         rep (i, 0, n - 1) scanf("%d", &s.arr[i]);
    94         rep (i, 0, m - 1) scanf("%d", &tar[i]);
    95         cout << bfs() << endl;
    96     }
    97     return 0;
    98 }
    View Code

    B:CSU1537模拟一遍

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FIN freopen("in.txt", "r", stdin)
    23 #define FOUT freopen("out.txt", "w", stdout)
    24 #define rep(i, a, b) for(int i = a; i <= b; i +=2)
    25  
    26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    32  
    33 //typedef __int64 LL;
    34 typedef long long LL;
    35 const int MAXN = 1010;
    36 const int MAXM = 2000010;
    37 const double eps = 1e-4;
    38  
    39 char s[200];
    40 int res;
    41  
    42 int equals1() {
    43     stack<int>st;
    44     st.push(s[0] - '0');
    45     int len = strlen(s);
    46     rep (i, 1, len-1) {
    47         if(s[i] == '+') st.push(s[i + 1] - '0');
    48         else st.top() = st.top() * (s[i + 1] - '0');
    49     }
    50     int ret = 0;
    51     while(!st.empty()) {
    52         ret += st.top(); st.pop();
    53     }
    54     return ret == res;
    55 }
    56  
    57 int equals2() {
    58     int len = strlen(s), ret = s[0] - '0';
    59     rep (i, 1, len-1) {
    60         if(s[i] == '+') ret += s[i + 1] - '0';
    61         else ret *= s[i + 1] - '0';
    62     }
    63     return ret == res;
    64 }
    65  
    66 int main()
    67 {
    68     //FIN;
    69     while(cin >> s >> res) {
    70         int ans1 = equals1(), ans2 = equals2();
    71         if(ans1) {
    72             if(ans2) puts("U");
    73             else puts("M");
    74         }
    75         else {
    76             if(ans2) puts("L");
    77             else puts("I");
    78         }
    79     }
    80     return 0;
    81 }
    View Code

    C:CSU1538分析一遍发现要走最少的路程,应该如果有交叉的区间,直接合并为一个大的区间,即若(a1, b1)与(a2, b2)满足a1 < a2,若a2 <= b1那么将其合并为(a1, b2)即应从a1走到b2再回到a1(这时就访问了b1与a2),再去到b2,证明也是可以证明的。

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FIN freopen("in.txt", "r", stdin)
    23 #define FOUT freopen("out.txt", "w", stdout)
    24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
    25  
    26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    32  
    33 //typedef __int64 LL;
    34 typedef long long LL;
    35 const int MAXN = 1010;
    36 const int MAXM = 2000010;
    37 const double eps = 1e-4;
    38  
    39 struct Node {
    40     int l, r;
    41     bool operator < (const Node& A) const {
    42         return l < A.l;
    43     }
    44 }l[10000];
    45 int n, m;
    46  
    47 int main()
    48 {
    49     //FIN;
    50     while(cin >> n >> m) {
    51         mem0(l);
    52         rep (i, 0, m - 1) {
    53             scanf("%d %d", &l[i].l, &l[i].r);
    54         }
    55         sort(l, l + m);
    56         int ans = n + 1, maxr = l[0].r, curl = l[0].l;
    57         rep (i, 1, m - 1) {
    58             if(l[i].l > maxr) {
    59                 ans += 2 * (maxr - curl);
    60                 curl = l[i].l;
    61                 maxr = l[i].r;
    62             }
    63             else maxr = max(l[i].r, maxr);
    64         }
    65         ans += 2 * (maxr - curl);
    66         cout << ans << endl;
    67     }
    68     return 0;
    69 }
    View Code

    D:CSU1539直接二分答案,通过V是可以算出是否可以通过每个杆的(这里还需要枚举反弹的次数,反正次数不多)。这里先贴上队友比赛时的代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <queue>
     5 #include <algorithm>
     6 #include <stack>
     7 #include <cmath>
     8 using namespace std;
     9 #define mem0(a) memset(a, 0, sizeof(a))
    10  
    11 const double eps = 1e-6;
    12 const double maxans = 1e6;
    13 const double pi = 3.14159265359;
    14 double d, p[20], h[20];
    15 int n, b;
    16 double calc(double x, double vx, double vy) {
    17     double a = -1.0 / 2 / vx / vx, b = vy / vx;
    18     return a * x * x + b * x;
    19 }
    20 bool Check(double v, int total) {
    21     double dd = d / total, sumd = 0, tt = dd / v / v;
    22     if (tt >= 1) return 0;
    23     double sita = asin(tt) / 2;
    24     sita = max(sita, pi / 2 - sita);
    25     double vx = v * cos(sita), vy = v * sin(sita);
    26     int now = 0;
    27     for (int i = 0; i < total; i++) {
    28         while (p[now] > sumd && p[now] < sumd + dd) {
    29             double x0 = p[now] - sumd;
    30             if (calc(x0, vx, vy) < h[now]) return 0;
    31             now++;
    32         }
    33         sumd += dd;
    34     }
    35     return 1;
    36 }
    37 double work(int total) {
    38     double l = 0.000001, r = maxans;
    39     while (fabs(r - l) > eps) {
    40         double m = (l + r) / 2;
    41         if (Check(m, total)) r = m;
    42         else l = m;
    43     }
    44     return l;
    45 }
    46 bool Conflict(int t) {
    47     for (int i = 0; i < t; i++) {
    48         double tmp = d / (t + 1) * (i + 1);
    49         for (int j = 0; j < n; j++) {
    50             if (fabs(p[j] - tmp) < eps) return 1;
    51         }
    52     }
    53     return 0;
    54 }
    55 int main()
    56 {
    57     //freopen("in.txt", "r", stdin);
    58     while(cin >> d >> n >> b) {
    59         for (int i = 0; i < n; i++) {
    60             cin >> p[i] >> h[i];
    61         }
    62         double ans = maxans;
    63         for (int i = 0; i <= b; i++) {
    64             if (Conflict(i)) continue;
    65             ans = min(ans, work(i + 1));
    66         }
    67         printf("%.5f
    ", ans);
    68     }
    69     return 0;
    70 }
    View Code

    E:CSU1540赛后花了比较多的时间去A掉这道题,看懂题花了比较大的精力,A掉他花了更大的精力,这里就讲讲题目意思吧:

    题目意思是说一辆车从起点开始随机到处乱走,现在知道的条件只有它从i - 1时刻到i时刻走了距离p,且i时刻GPS测出来的前进方向是d方向(E, W, N, S),问在最后的t时刻这辆车会停留在哪些位置。另外一个条件就是说若 k 时刻这辆车正在一个拐弯处,那么GPS测出来的时间可能是转弯前的方向,也有可能是转弯后的方向。

    注意看数据范围  x , y <= 50  这时候我想你们知道该怎么做了= =(dfs+状态标记。。)

    调试的我想死啊。。。

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <cstdio>
      9 #include <cctype>
     10 #include <cstring>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 #define INF 0x3f3f3f3f
     16 #define inf (-((LL)1<<40))
     17 #define lson k<<1, L, mid
     18 #define rson k<<1|1, mid+1, R
     19 #define mem0(a) memset(a,0,sizeof(a))
     20 #define mem1(a) memset(a,-1,sizeof(a))
     21 #define mem(a, b) memset(a, b, sizeof(a))
     22 #define FIN freopen("in.txt", "r", stdin)
     23 #define FOUT freopen("out.txt", "w", stdout)
     24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
     25  
     26 template<class T> int CMP_MIN(T a, T b) { return a < b; }
     27 template<class T> int CMP_MAX(T a, T b) { return a > b; }
     28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
     29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
     30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
     31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
     32  
     33 //typedef __int64 LL;
     34 typedef long long LL;
     35 const int MAXN = 1010;
     36 const int MAXM = 20010;
     37 const double eps = 1e-4;
     38  
     39 const int dx[4] = {0, -1, 0, 1};
     40 const int dy[4] = {1, 0, -1, 0};
     41 char pas[5] = {"NWSE"};
     42 int DN = 0, DS = 2, DE = 3, DW = 1;
     43  
     44 struct Point {
     45     int x, y, d;
     46     Point(){}
     47     Point(int _x, int _y, int _d){
     48         x = _x; y = _y, d = _d;
     49     }
     50     bool operator < (Point& A) const {
     51         return x != A.x ? x < A.x : y < A.y;
     52     }
     53 }st, q[2][3000];
     54 struct Line {
     55     Point u, v;
     56 }v[100], h[100], tmp;
     57 int cnt[2], n, t, vcnt, hcnt, e[60][60][5];
     58 bool vis[55][55][4][20];
     59  
     60 void addEdge() {
     61     mem0(e);
     62     rep (i, 0, vcnt - 1) rep (j, 0, hcnt - 1) {
     63         if(h[j].u.y < v[i].u.y || h[j].u.y > v[i].v.y
     64             || v[i].u.x < h[j].u.x || v[i].u.x > h[j].v.x) continue;
     65         int fo[4] = {0};
     66         if(v[i].v.y == h[j].u.y) fo[0] = 1;
     67         if(v[i].u.x == h[j].u.x) fo[1] = 1;
     68         if(v[i].u.y == h[j].u.y) fo[2] = 1;
     69         if(v[i].u.x == h[j].v.x) fo[3] = 1;
     70         rep (k, 0, 3) if(!fo[k]) {
     71             e[v[i].u.x][h[j].u.y][k] = 1;
     72         }
     73     }
     74     rep (i, 0, vcnt - 1) {
     75         int curx = v[i].u.x, miny = v[i].u.y, maxy = v[i].v.y;
     76         rep (j, miny, maxy) {
     77             if(j < maxy) e[curx][j][DN] = 1;
     78             if(j > miny) e[curx][j][DS] = 1;
     79         }
     80     }
     81     rep (i, 0, hcnt - 1) {
     82         int minx = h[i].u.x, maxx = h[i].v.x, cury = h[i].u.y;
     83         rep (j, minx, maxx) {
     84             if(j < maxx) e[j][cury][DE] = 1;
     85             if(j > minx) e[j][cury][DW] = 1;
     86         }
     87     }
     88 }
     89  
     90 int check(int x, int y, int od, int d, int s)
     91 {
     92     int isN = e[x][y][DN], isS = e[x][y][DS], isE = e[x][y][DE], isW = e[x][y][DW];
     93     int sum = isN + isS + isW + isE;
     94     if(sum == 4) {
     95         if(od == s) return d != (s + 2) % 4;
     96         return d == s;
     97     }
     98     if(sum == 3){
     99         return s != od ? d == s : 1;
    100     }
    101     if(sum == 2) {
    102         if(isN&&isS || isE&&isW) return s == d && d == od;
    103         int a = isN ? DN : DS, b = isE ? DE : DW;
    104         if((a + 2) % 4 == od) return (s == od || s == b) && d == b;
    105         if((b + 2) % 4 == od) return (s == od || s == a) && d == a;
    106     }
    107     return 1;
    108 }
    109  
    110 void dfs(int x, int y, int odir, int dir, int seems, int now, int s)
    111 {
    112     if(s == 0) {
    113         if(check(x, y, odir, dir, seems)) {
    114             q[now][cnt[now]++] = Point(x, y, dir);
    115         }
    116         return ;
    117     }
    118     if(vis[x][y][dir][s]) return ;
    119     vis[x][y][dir][s] = 1;
    120     x += dx[dir]; y += dy[dir];
    121     rep (i, 0, 3) if(e[x][y][i] && (i + 2) % 4 != dir) {
    122         dfs(x, y, dir, i, seems, now, s - 1);
    123     }
    124 }
    125  
    126 int conv(char ch) {
    127     if(ch == 'N') return DN;
    128     if(ch == 'S') return DS;
    129     if(ch == 'E') return DE;
    130     return DW;
    131 }
    132  
    133 int cmp(Point a, Point b) {
    134     return a < b;
    135 }
    136  
    137 int main()
    138 {
    139  
    140     while(~scanf("%d %d %d %d", &n, &st.x, &st.y, &t)) {
    141         vcnt = hcnt = 0;
    142         mem0(cnt);
    143         rep (i, 0, n - 1) {
    144             scanf("%d %d %d %d", &tmp.u.x, &tmp.u.y, &tmp.v.x, &tmp.v.y);
    145             if(tmp.u.x > tmp.v.x) swap(tmp.u.x, tmp.v.x);
    146             if(tmp.u. y > tmp.v.y) swap(tmp.u.y, tmp.v.y);
    147             if(tmp.u.x == tmp.v.x) v[vcnt++] = tmp;
    148             else h[hcnt++] = tmp;
    149             //printf("%d %d %d %d
    ", tmp.u.x, tmp.u.y, tmp.v.x, tmp.v.y);
    150         }
    151         addEdge();
    152         int now = 0, step = 0; char dir;
    153         rep (i, 0, 3) if(e[st.x][st.y][i]) {
    154             q[now][cnt[now]++] = Point(st.x, st.y, i);
    155         }
    156         rep (i, 0, t - 1) {
    157             scanf("%d %c", &step, &dir);
    158             now = !now; mem0(vis); cnt[now] = 0;
    159             rep (j, 0, cnt[!now] - 1) {
    160                 dfs(q[!now][j].x, q[!now][j].y, -1, q[!now][j].d, conv(dir), now, step);
    161             }
    162         }
    163         sort(q[now], q[now] + cnt[now], cmp);
    164         int lax = -1, lay = -1;
    165         rep (i, 0, cnt[now] - 1) if(q[now][i].x != lax || q[now][i].y != lay) {
    166             printf("%d %d
    ", q[now][i].x, q[now][i].y);
    167             lax = q[now][i].x;
    168             lay = q[now][i].y;
    169         }
    170     }
    171     return 0;
    172 }
    View Code

    F:CSU1541题目大意就是给一个图,问为了构建最先生成树,哪些边是不可被替代的,(不可被替代就是说如果这条边被删除,最小生成树的权值会变大)

    上面已经说了如果被删除权值会变大就是不可替代的,所以先求一遍最小生成树,然后枚举最小生成树的边,删除看最小生成树权值是否变大,或图是否还连通,这样复杂度就是O(m * logm) + O(m * n),正好可以过

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FIN freopen("in.txt", "r", stdin)
    23 #define FOUT freopen("out.txt", "w", stdout)
    24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
    25  
    26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    32  
    33 //typedef __int64 LL;
    34 typedef long long LL;
    35 const int MAXN = 1010;
    36 const int MAXM = 2000010;
    37 const double eps = 1e-4;
    38  
    39 struct Edge {
    40     int u, v, w;
    41     bool operator < (const Edge& A) const {
    42         return w < A.w;
    43     }
    44 }e[51000];
    45  
    46 int minE[51000], cnt, fa[510], n, m;
    47  
    48 int findP(int x) { return x == fa[x] ? x : fa[x] = findP(fa[x]); }
    49  
    50 int kruskal(int forbidon) {
    51     int ret = 0, num = n - 1;
    52     rep (i, 0, n) fa[i] = i;
    53     rep (i, 0, m - 1) if(i != forbidon) {
    54         int x = findP(e[i].u), y = findP(e[i].v);
    55         if(x != y) {
    56             ret += e[i].w;
    57             fa[x] = y;
    58             if(forbidon < 0) minE[cnt++] = i;
    59             num --;
    60         }
    61     }
    62     return ret = num ? INF : ret;
    63 }
    64  
    65 int main()
    66 {
    67     //FIN;
    68     while(cin >> n >> m) {
    69         rep (i, 0, m - 1) scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
    70         sort(e, e + m);
    71         cnt  = 0;
    72         int minW = kruskal(-1);
    73         int num = 0, sum = 0;
    74         rep (i, 0, cnt - 1) {
    75             if(kruskal(minE[i]) > minW) num ++, sum += e[minE[i]].w;
    76         }
    77         cout << num << " " << sum << endl;
    78     }
    79     return 0;
    80 }
    View Code

    G:题目是说一个原始匹配的括号序列,每次将位置p的括号反转,问最左侧需要将哪个括号反转使得括号序列重新获得匹配。

    结题报告:http://www.cnblogs.com/gj-Acit/p/4361520.html

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <cstdio>
      9 #include <cctype>
     10 #include <cstring>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 #define INF 0x3f3f3f3f
     16 #define inf (-((LL)1<<40))
     17 #define lson k<<1, L, mid
     18 #define rson k<<1|1, mid+1, R
     19 #define mem0(a) memset(a,0,sizeof(a))
     20 #define mem1(a) memset(a,-1,sizeof(a))
     21 #define mem(a, b) memset(a, b, sizeof(a))
     22 #define FIN freopen("in.txt", "r", stdin)
     23 #define FOUT freopen("out.txt", "w", stdout)
     24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
     25 
     26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
     27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
     28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
     29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
     30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
     31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
     32 
     33 //typedef __int64 LL;
     34 typedef long long LL;
     35 const int MAXN = 1010;
     36 const int MAXM = 20010;
     37 const double eps = 1e-4;
     38 
     39 int n, q, p, len;
     40 char s[310000]={"1"};
     41 struct Node {
     42     int f, a, s;
     43 }t[310000<<2];
     44 
     45 char rev(char c) { return (c == '(') ? ')' : '('; }
     46 
     47 void buildTree(int k, int L, int R, int p, int a)
     48 {
     49     t[k].s = 0;
     50     if(L == R) {
     51         t[k].f = a - L; t[k].a = a;
     52         return ;
     53     }
     54     int mid = (L + R) >> 1;
     55     if(p > mid) buildTree(rson, p, a);
     56     else buildTree(lson, p, a);
     57     t[k].f = min(t[k<<1].f, t[k<<1|1].f);
     58     t[k].a = min(t[k<<1].a, t[k<<1|1].a);
     59 }
     60 
     61 void init()
     62 {
     63     mem0(t);
     64     int sum = 0;
     65     len = strlen(s) - 1;
     66     rep (i, 1, len) {
     67         sum += (s[i] == '(') ? 1 : -1;
     68         buildTree(1, 1, len, i, sum);//建树
     69     }
     70 }
     71 
     72 //向下传延时标记
     73 void pushDown(int k)
     74 {
     75     t[k<<1].s += t[k].s; t[k<<1].a += t[k].s; t[k<<1].f += t[k].s;
     76     t[k<<1|1].s += t[k].s; t[k<<1|1].a += t[k].s; t[k<<1|1].f += t[k].s;
     77     t[k].s = 0;
     78 }
     79 
     80 //更新操作,将区间[p, len]的所有值都+val
     81 void update(int k, int L, int R, int p, int val)
     82 {
     83     if(p <= L) {
     84         t[k].s += val;
     85         t[k].a += val;
     86         t[k].f += val;
     87         return ;
     88     }
     89     pushDown(k);
     90     int mid = (L + R) >> 1;
     91     if(p <= mid) update(lson, p, val);//左侧可能需要更新
     92     update(rson, p, val);//右侧是一定要更新的,因为需要更新的区间为[p, len]
     93     t[k].f = min(t[k<<1].f, t[k<<1|1].f);
     94     t[k].a = min(t[k<<1].a, t[k<<1|1].a);
     95 }
     96 
     97 //查询最左侧的右括号
     98 int query1(int k, int L, int R)
     99 {
    100     if(L == R) return L;
    101     int mid = (L + R) >> 1;
    102     pushDown(k);
    103     if(t[k<<1].f < 0) return query1(lson);
    104     return query1(rson);
    105 }
    106 
    107 //查询从len往前连续的最长的满足a>=2的点,也就是最后一个<2的位置+1
    108 int query2(int k, int L, int R)
    109 {
    110     if(L == R) return min(len, L + 1);
    111     int mid = (L + R) >> 1;
    112     pushDown(k);
    113     if(t[k<<1|1].a < 2) return query2(rson);
    114     return query2(lson);
    115 }
    116 
    117 int main()
    118 {
    119     //FIN;
    120     while(~scanf("%d %d%*c %s", &n, &q, s + 1)) {
    121         init();
    122         rep (i, 0, q - 1) {
    123             scanf("%d", &p);
    124             s[p] = rev(s[p]); update(1, 1, len, p, s[p] == ')' ? -2 : 2);
    125             if(s[p] == ')') p = query1(1, 1, len);//find first )
    126             else p = query2(1, 1, len); //find last < 2
    127             s[p] = rev(s[p]); update(1, 1, len, p, s[p] == ')' ? -2 : 2);
    128             printf("%d
    ", p);
    129         }
    130     }
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    Spring Boot使用@Scheduled定时器任务
    [TaskList] 省选前板子补完计划
    [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算
    网络流刷题日记
    [模板] 网络流相关/最大流ISAP/费用流zkw
    11/5/2018模拟 Problem C
    11/1/2018模拟 Max
    [模板] 笛卡尔树 && RMQ
    bzoj1010-[HNOI2008]玩具装箱toy
    [模板] 斜率优化
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/4375075.html
Copyright © 2011-2022 走看看