2018 Multi-University Training Contest 6

不知不觉拖欠了两周阿哈哈哈哈或

 

1001 oval-and-rectangle

谈学姐最喜欢积分了 不写SPJ最牛逼了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long T,a,b,i,j,k,s,t;
 4 double ans,temp=asin(1.0);
 5 int main()
 6 {
 7         scanf("%lld",&T);
 8         while (T--)
 9         {
10                 scanf("%lld%lld",&a,&b);
11                 ans=2*b+2*a*temp;
12                 s=(long long) (ans*1000000);
13                 ans=s*0.000001;
14                 printf("%.6f\n",ans);
15         }
16 }
谈学姐

 

1002 bookshelf

就俩结论$gcd(2^a - 1, 2^b - 1) = 2^{gcd(a, b)} - 1$,这个其实就是辗转相除的过程

$gcd(fib[a], fib[b]) = fib[gcd(a, b)]$,这个有点麻烦吧百度有一堆证明,敝队比较菜打表看出来的

问题就转变为求$gcd$为$g$的整数拆分,因为$g$要是$n$的约数,根号拆分暴力容斥一下就好了

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 long long ans,n,i,j,k,s,t,sum,mod=1e9+7;
  4 long long a[1000010],b[1000010],mob[1000010],f[1000010],fac[2000010],invfac[2000010];
  5 long long ksm(long long x,long long y,long long mod)
  6 {
  7         long long temp=1;
  8         x%=mod;
  9         while (y>0)
 10         {
 11                 if (y%2==1) temp=temp*x%mod;
 12                 x=x*x%mod;
 13                 y/=2;
 14         }
 15         return temp;
 16 }
 17 long long cc(long long n,long long m)
 18 {
 19         long long temp=fac[n]*invfac[m]%mod;
 20         temp=temp*invfac[n-m]%mod;
 21         return temp;
 22 }
 23 int main()
 24 {
 25         f[1]=1;f[2]=1;
 26         for (i=3;i<=1000000;i++)
 27         {
 28                 f[i]=((f[i-1]+1)*(f[i-2]+1)-1)%mod;
 29         }
 30         fac[0]=invfac[0]=1;
 31         for (i=1;i<=2000000;i++)
 32         {
 33                 fac[i]=fac[i-1]*i%mod;
 34         }
 35         invfac[2000000]=ksm(fac[2000000],mod-2,mod);
 36         for (i=1999999;i>=1;i--)
 37         {
 38                 invfac[i]=invfac[i+1]*(i+1)%mod;
 39         }
 40         sum=0;
 41         mob[1]=1;
 42         for (i=2;i<=1000000;i++)
 43         {
 44                 if (a[i]==0)
 45                 {
 46                         sum++;
 47                         b[sum]=i;
 48                         mob[i]=-1;
 49                 }
 50                 for (j=1;j<=sum;j++)
 51                 {
 52                         s=i*b[j];
 53                         if (s>100000) break;
 54                         a[s]=1;
 55                         mob[s]=-mob[i];
 56                         if (i%b[j]==0)
 57                         {
 58                                 mob[s]=0;
 59                                 break;
 60                         }
 61                 }
 62         }
 63         int T;
 64         scanf("%d",&T);
 65         while (T--)
 66         {
 67                 scanf("%lld%lld",&n,&k);
 68                 ans=0;s=0;sum=0;
 69                 for (i=1;i<=int(sqrt(n));i++)
 70                 {
 71                         if (n%i==0)
 72                         {
 73                                 sum++;
 74                                 a[sum]=i;
 75                                 b[sum]=n/i;
 76                         }
 77                 }
 78                 t=sum;
 79                 if (a[t]==b[t]) t--;
 80                 for (i=t;i>=1;i--)
 81                 {
 82                         sum++;
 83                         a[sum]=b[i];
 84                 }
 85                 for (i=1;i<=sum;i++) b[i]=cc(n/a[i]+k-1,k-1);
 86                 for (i=sum;i>=1;i--)
 87                 {
 88                         if (n%a[i]==0)
 89                         {
 90                                 t=b[i];
 91                                 ans=(ans+f[a[i]]*t)%mod;
 92                                 for (j=1;j<i;j++)
 93                                         if (a[i]%a[j]==0) b[j]=(b[j]-b[i])%mod;
 94                         }
 95                 }
 96                 s=cc(n+k-1,k-1);
 97                 ans=ans*ksm(s,mod-2,mod)%mod;
 98                 if (ans<0) ans+=mod;
 99                 printf("%lld\n",ans);
100         }
101 }
谈学姐

 

1003 Ringland

首先容易看出来是枚举一个起点,然后顺序匹配下去最优

因为距离是$\min(|a_{i} - b_{j}|, L - |a_{i} - b_{j}|)$,把$b$开三倍就可以断环为链,问题转化为$\min\limits_{bias} \sum_{i = 1} ^{n} |a_{i} - b_{i + bias}|$

这样$a_{i}$和$b_{i}$的贡献都只有正负两种,只要找到正负分界点,对第二段$b$维护最大的小于$b_{i}$的$a_{p}$位置双指针扫一遍即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 5e5 + 10;
 5 int a[maxn], b[maxn * 3];
 6 ll del[maxn * 2];
 7 
 8 int main() {
 9     int T;
10     scanf("%d", &T);
11     while(T--) {
12         int N, L, p = 1;
13         scanf("%d %d", &N, &L);
14         for(int i = 1; i <= N; ++i) scanf("%d", a + i);
15         for(int i = 1; i <= N; ++i) {
16             scanf("%d", b + N + i);
17             b[i] = b[N + i] - L;
18             b[N + N + i] = b[N + i] + L;
19         }
20         for(int i = 1; i <= N + N + 1; ++i) del[i] = 0;
21         for(int i = 1; i <= N; ++i) {
22             del[1] += a[i] - b[i];
23             del[i + 1] += b[i];
24             del[i + N + 1] += b[i + N + N];
25         }
26         for(int i = N + 1; i <= N + N; ++i) {
27             while(p <= N && a[p] <= b[i]) del[i - p + 2] -= 2 * a[p++];
28             del[i - N + 1] -= b[i];
29             del[i - p + 2] += 2 * b[i];
30             del[i + 1] -= b[i];
31         }
32         while(p <= N) del[N + N + 3 - p] -= 2 * a[p++];
33         ll t = 0, ans = 1e18;
34         for(int i = 1; i <= N + N + 1; ++i) t += del[i], ans = min(ans, t);
35         printf("%lld\n", ans);
36     }
37     return 0;
38 }
Aguin

 

1004 Shoot Game

看完题解恍然大悟?其实状态并不是那么好想呀……

因为要$f[i][j]$表示消除被区间$[i, j]$完全包含的线段,然后枚举中间点$k$时,被$[i, j]$完全包含而不被$[i, k - 1]$或者$[k + 1, j]$包含的一定经过$k$了

每次枚举最大的转移,如果这个区间没有包含任何线段就是$0$,多个最大的没有影响……

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll inf = 1e18;
 5 int H[333], L[333], R[333], W[333];
 6 ll f[666][666];
 7 struct P {
 8     int y, x;
 9     friend bool operator < (P A, P B) {
10         return 1ll * A.x * B.y < 1ll * B.x * A.y;
11     }
12     friend bool operator == (P A, P B) {
13         return !(A < B) && !(B < A);
14     }
15 };
16 vector<P> v;
17 
18 int main() {
19     int T;
20     scanf("%d", &T);
21     while(T--) {
22         int n;
23         scanf("%d", &n);
24         v.clear();
25         for(int i = 1; i <= n; ++i) {
26             scanf("%d %d %d %d", H + i, L + i, R + i, W + i);
27             v.emplace_back(P{H[i], L[i]});
28             v.emplace_back(P{H[i], R[i]});
29         }
30         sort(v.begin(), v.end());
31         v.erase(unique(v.begin(), v.end()), v.end());
32         int sz = v.size();
33         for(int i = 1; i <= n; ++i) {
34             L[i] = lower_bound(v.begin(), v.end(), P{H[i], L[i]}) - v.begin() + 1;
35             R[i] = lower_bound(v.begin(), v.end(), P{H[i], R[i]}) - v.begin() + 1;
36         }
37         for(int l = 1; l <= sz; ++l) {
38             for(int s = 1; s + l - 1 <= sz; ++s) {
39                 int e = s + l - 1, mx = -1, p = 0;
40                 f[s][e] = inf;
41                 for(int i = 1; i <= n; ++i) {
42                     if(s <= L[i] && R[i] <= e && W[i] > mx)
43                         mx = W[i], p = i;
44                 }
45                 if(!p) f[s][e] = 0;
46                 else for(int i = L[p]; i <= R[p]; ++i) {
47                     f[s][e] = min(f[s][e], f[s][i - 1] + mx + f[i + 1][e]);
48                 }
49             }
50         }
51         printf("%lld\n", f[1][sz]);
52     }
53     return 0;
54 }
Aguin

 

1005 black-and-white

观察一下发现必有一点是在所在行/列的最靠边的一个黑格,这样的黑格是$O(n)$的,如果两个都是靠边的可以$O(n^2)$暴力一下

否则枚举不靠边的那个点,另一个靠边的点只能在四个角的矩形范围内,比较好写的方法是预处理每个点左上角中靠边点$i + j$的最小值和数目,然后翻三次

看了题解感觉想法挺简单的……写着写着就自闭了……

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 short L[2005][2005], U[2005][2005];
  4 bool G[2005][2005], b[2005][2005];
  5 short f[2005][2005], g[2005][2005];
  6 char s[2005];
  7 
  8 int mx, num;
  9 inline void up(int x, int y = 1) {
 10     if(x == mx) num += y;
 11     else if(x > mx) mx = x, num = y;
 12 }
 13 
 14 inline void flip(int N) {
 15     static bool G_[2005][2005], b_[2005][2005];
 16     for(int i = 1; i <= N; ++i)
 17         for(int j = 1; j <= N; ++j)
 18             G_[i][j] = G[i][j], b_[i][j] = b[i][j];
 19     for(int i = 1; i <= N; ++i)
 20         for(int j = 1; j <= N; ++j)
 21             G[i][j] = G_[N + 1 - j][i], b[i][j] = b_[N + 1 - j][i];
 22 }
 23 
 24 typedef pair<int, int> pii;
 25 vector<pii> v;
 26 int main() {
 27     int T;
 28     scanf("%d", &T);
 29     while(T--) {
 30         mx = -1, num = 0;
 31         int N;
 32         scanf("%d", &N);
 33         for(int i = 1; i <= N; ++i) {
 34             scanf("%s", s + 1);
 35             for(int j = 1; j <= N; ++j) G[i][j] = s[j] == '1', b[i][j] = 0;
 36         }
 37         // 同行同列
 38         for(int i = 1; i <= N; ++i) {
 39             int col = 0, fi = 0;
 40             for(int j = 1; j <= N; ++j) {
 41                 if(G[i][j]) {
 42                     L[i][j] = L[i][j - 1] + 1, U[i][j] = U[i - 1][j] + 1;
 43                     if(!col) b[i][j] = 1, fi = j;
 44                     col = j;
 45                 }
 46                 else L[i][j] = U[i][j] = 0;
 47             }
 48             if(col && col - L[i][col] + 1 > fi) up(col - fi);
 49             b[i][col] = 1;
 50         }
 51         for(int j = N; j >= 1; --j) {
 52             int row = 0, fi = 0;
 53             for(int i = N; i >= 1; --i) {
 54                 if(G[i][j]) {
 55                     if(!row) b[i][j] = 1, fi = i;
 56                     row = i;
 57                 }
 58             }
 59             if(row && fi - U[fi][j] + 1 > row) up(fi - row);
 60             b[row][j] = 1;
 61         }
 62         v.clear();
 63         for(int i = 1; i <= N; ++i) {
 64             for(int j = 1; j <= N; ++j) {
 65                 if(b[i][j]) v.emplace_back(pii(i, j));
 66             }
 67         }
 68         // 两边缘
 69         int sz = v.size();
 70         for(int i = 0; i < sz; ++i) {
 71             int x1 = v[i].first, y1 = v[i].second;
 72             for(int j = i + 1; j < sz; ++j) {
 73                 int x2 = v[j].first, y2 = v[j].second;
 74                 if(x1 == x2 || y1 == y2) continue;
 75                 if(y1 > y2) {
 76                     if(y1 - L[x2][y1] + 1 <= y2 && x2 - U[x2][y1] + 1 <= x1) continue;
 77                     if(y1 - L[x1][y1] + 1 <= y2 && x2 - U[x2][y2] + 1 <= x1) continue;
 78                     up(y1 - y2 + x2 - x1);
 79                 }
 80                 else {
 81                     if(y2 - L[x2][y2] + 1 <= y1 && x2 - U[x2][y1] + 1 <= x1) continue;
 82                     if(y2 - L[x1][y2] + 1 <= y1 && x2 - U[x2][y2] + 1 <= x1) continue;
 83                     up(y2 - y1 + x2 - x1);
 84                 }
 85             }
 86         }
 87         // 一边缘
 88         for(int d = 0; d < 4; ++d) {
 89             if(d) {
 90                 flip(N);
 91                 for(int i = 1; i <= N; ++i)
 92                     for(int j = 1; j <= N; ++j)
 93                         if(G[i][j]) L[i][j] = L[i][j - 1] + 1, U[i][j] = U[i - 1][j] + 1;
 94                         else L[i][j] = U[i][j] = 0;
 95             }
 96             for(int i = 0; i <= N; ++i)
 97                 for(int j = 0; j <= N; ++j)
 98                     f[i][j] = 3 * N;
 99             for(int i = 1; i <= N; ++i) {
100                 for(int j = 1; j <= N; ++j) {
101                     int mx = min(f[i - 1][j], f[i][j - 1]), x = 0;
102                     if(b[i][j] && i + j < mx) mx = i + j;
103                     if(f[i - 1][j] == mx) x += g[i - 1][j];
104                     if(f[i][j - 1] == mx) x += g[i][j - 1];
105                     if(f[i - 1][j - 1] == mx) x -= g[i - 1][j - 1];
106                     if(b[i][j] && i + j == mx) x++;
107                     f[i][j] = mx, g[i][j] = x;
108                     if(G[i][j] && !b[i][j]) {
109                         if(L[i][j] == j || U[i][j] == i) continue;
110                         int x = i - U[i][j], y = j - L[i][j];
111                         up(i + j - f[x][y], g[x][y]);
112                     }
113                 }
114             }
115         }
116         printf("%d %d\n", mx, num);
117     }
118     return 0;
119 }
Aguin

 

1006 foam-transformation

因为T操作是加一个二次函数,相当于对三次差分后随便选相邻两个位置$+x$,因此问题等价于多少个子串交错和为$0$

又可以证明,后面加了五个零后,三次差分交错和为$0$,原数列交错和也为$0$,只需维护原数列交错和

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5 + 10;
 5 ll a[maxn], sum[maxn], ans;
 6 map<ll, int> mp;
 7 
 8 inline void upd(int i, int x) {
 9     mp[sum[i]]--;
10     ans -= mp[sum[i]];
11     if(i & 1) sum[i] += x;
12     else sum[i] -= x;
13     ans += mp[sum[i]];
14     mp[sum[i]]++;
15 }
16 
17 int main() {
18     int T;
19     scanf("%d", &T);
20     while(T--) {
21         int n, m;
22         scanf("%d %d", &n, &m);
23         mp.clear();
24         mp[0] = 1;
25         ans = 0;
26         for(int i = 1; i <= n; ++i) {
27             scanf("%lld", a + i);
28             if(i & 1) sum[i] = sum[i - 1] + a[i];
29             else sum[i] = sum[i - 1] - a[i];
30             ans += mp[sum[i]];
31             mp[sum[i]]++;
32         }
33         printf("%lld\n", ans);
34         while(m--) {
35             int i, x;
36             char s[11];
37             scanf("%s%d%d", s, &i, &x);
38             upd(i, x);
39             printf("%lld\n", ans);
40         }
41     }
42     return 0;
43 }
Aguin

 

1007 Variance-MST

LOJ #2469……应该不补了

 

1008 Rectangle Outline

题解证明了一个轮廓线最多不超过$8n$个拐点,考虑扫描线去抠边界,就是覆盖次数由$0$变成$1$的区间,用线段树暴力抠,因为不超过$8n$,如果某一次超过就直接跳出

抠出来以后建图判断一下是不是一个环

不想动脑子,四个方向的部分直接copy-paste了

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 1e5 + 10;
  4 typedef pair<int, int> pii;
  5 int mx[maxn], my[maxn], Mx[maxn], My[maxn];
  6 vector<int> b;
  7 
  8 struct seg {
  9     int h, l, r, o;
 10 };
 11 vector<seg> S;
 12 bool cmp1(seg A, seg B) {
 13     if(A.h != B.h) return A.h < B.h;
 14     return A.o > B.o;
 15 }
 16 bool cmp2(seg A, seg B) {
 17     if(A.h != B.h) return A.h > B.h;
 18     return A.o > B.o;
 19 }
 20 
 21 int M[maxn << 4], mi[maxn << 4], tag[maxn << 4];
 22 inline void gather(int p) {
 23     M[p] = max(M[p << 1], M[p << 1 | 1]);
 24     mi[p] = min(mi[p << 1], mi[p << 1 | 1]);
 25 }
 26 inline void push(int p) {
 27     if (tag[p]) {
 28         tag[p << 1] += tag[p];
 29         tag[p << 1 | 1] += tag[p];
 30         M[p << 1] += tag[p];
 31         M[p << 1 | 1] += tag[p];
 32         mi[p << 1] += tag[p];
 33         mi[p << 1 | 1] += tag[p];
 34         tag[p] = 0;
 35     }
 36 }
 37 void build(int p, int l, int r) {
 38     tag[p] = 0;
 39     if (l < r) {
 40         int mid = (l + r) >> 1;
 41         build(p << 1, l, mid);
 42         build(p << 1 | 1, mid + 1, r);
 43         gather(p);
 44     } else M[p] = mi[p] = 0;
 45 }
 46 void modify(int p, int tl, int tr, int l, int r, int v) {
 47     if (tl > tr) return;
 48     if (tr < l || r < tl) return;
 49     if (l <= tl && tr <= r) {
 50         tag[p] += v;
 51         M[p] += v;
 52         mi[p] += v;
 53         return;
 54     }
 55     push(p);
 56     int mid = (tl + tr) >> 1;
 57     modify(p << 1, tl, mid, l, r, v);
 58     modify(p << 1 | 1, mid + 1, tr, l, r, v);
 59     gather(p);
 60 }
 61 vector<pii> ret;
 62 void query(int p, int tl, int tr, int l, int r) {
 63     if (tl > tr) return;
 64     if (tr < l || r < tl) return;
 65     if (mi[p] > 0) return;
 66     if (l <= tl && tr <= r && M[p] == 0) {
 67         ret.emplace_back(pii(tl - 1, tr));
 68         return;
 69     }
 70     push(p);
 71     int mid = (tl + tr) >> 1;
 72     query(p << 1, tl, mid, l, r), query(p << 1 | 1, mid + 1, tr, l, r);
 73 }
 74 
 75 map< pii, vector<pii> > G;
 76 vector<pii> ans;
 77 void get(pii x, pii f, pii rt) {
 78     int ok = 1;
 79     while(ok) {
 80         ok = 0;
 81         ans.push_back(x);
 82         for(int i = 0; i < G[x].size(); ++i) {
 83             pii to = G[x][i];
 84             if(to == f || to == rt) continue;
 85             ok = 1, f = x, x = to; break;
 86         }
 87     }
 88 }
 89 int main() {
 90     int T;
 91     scanf("%d", &T);
 92     while(T--) {
 93         int n, ok = 1;
 94         scanf("%d", &n);
 95         b.clear();
 96         for(int i = 1; i <= n; ++i) {
 97             scanf("%d %d %d %d", mx + i, my + i, Mx + i, My + i);
 98             b.push_back(mx[i]), b.push_back(my[i]);
 99             b.push_back(Mx[i]), b.push_back(My[i]);
100         }
101         sort(b.begin(), b.end());
102         b.erase(unique(b.begin(), b.end()), b.end());
103         for(int i = 1; i <= n; ++i) {
104             mx[i] = lower_bound(b.begin(), b.end(), mx[i]) - b.begin();
105             my[i] = lower_bound(b.begin(), b.end(), my[i]) - b.begin();
106             Mx[i] = lower_bound(b.begin(), b.end(), Mx[i]) - b.begin();
107             My[i] = lower_bound(b.begin(), b.end(), My[i]) - b.begin();
108         }
109         G.clear();
110         S.clear();
111         for(int i = 1; i <= n; ++i) {
112             S.emplace_back(seg{mx[i], my[i], My[i], 1});
113             S.emplace_back(seg{Mx[i], my[i], My[i], -1});
114         }
115         sort(S.begin(), S.end(), cmp1);
116         build(1, 1, b.size());
117         for(int i = 0; i < S.size(); ++i) {
118             if(S[i].o == -1) {
119                 modify(1, 1, b.size(), S[i].l + 1, S[i].r, -1);
120                 continue;
121             }
122             int j = i;
123             while(j + 1 < S.size() && S[j + 1].h == S[j].h && S[j + 1].o == 1) ++j;
124             ret.clear();
125             for(int k = i; k <= j; ++k) {
126                 query(1, 1, b.size(), S[k].l + 1, S[k].r);
127                 modify(1, 1, b.size(), S[k].l + 1, S[k].r, 1);
128             }
129             sort(ret.begin(), ret.end());
130             vector<pii> tmp;
131             for(int k = 0; k < ret.size(); ++k) {
132                 int sz = tmp.size();
133                 if(sz && tmp[sz - 1].second >= ret[k].first) {
134                     ret[k] = pii(tmp[sz - 1].first, ret[k].second);
135                     tmp.pop_back(), tmp.push_back(ret[k]);
136                 }
137                 else tmp.push_back(ret[k]);
138             }
139             for(int k = 0; k < tmp.size(); ++k) {
140                 G[pii(S[i].h, tmp[k].first)].emplace_back(pii(S[i].h, tmp[k].second));
141                 G[pii(S[i].h, tmp[k].second)].emplace_back(pii(S[i].h, tmp[k].first));
142             }
143             if(G.size() >= 8 * n) {ok = 0; break;}
144             i = j;
145         }
146         if(!ok) {puts("Oops!"); continue;}
147         S.clear();
148         for(int i = 1; i <= n; ++i) {
149             S.emplace_back(seg{Mx[i], my[i], My[i], 1});
150             S.emplace_back(seg{mx[i], my[i], My[i], -1});
151         }
152         sort(S.begin(), S.end(), cmp2);
153         build(1, 1, b.size());
154         for(int i = 0; i < S.size(); ++i) {
155             if(S[i].o == -1) {
156                 modify(1, 1, b.size(), S[i].l + 1, S[i].r, -1);
157                 continue;
158             }
159             int j = i;
160             while(j + 1 < S.size() && S[j + 1].h == S[j].h && S[j + 1].o == 1) ++j;
161             ret.clear();
162             for(int k = i; k <= j; ++k) {
163                 query(1, 1, b.size(), S[k].l + 1, S[k].r);
164                 modify(1, 1, b.size(), S[k].l + 1, S[k].r, 1);
165             }
166             sort(ret.begin(), ret.end());
167             vector<pii> tmp;
168             for(int k = 0; k < ret.size(); ++k) {
169                 int sz = tmp.size();
170                 if(sz && tmp[sz - 1].second >= ret[k].first) {
171                     ret[k] = pii(tmp[sz - 1].first, ret[k].second);
172                     tmp.pop_back(), tmp.push_back(ret[k]);
173                 }
174                 else tmp.push_back(ret[k]);
175             }
176             for(int k = 0; k < tmp.size(); ++k) {
177                 G[pii(S[i].h, tmp[k].first)].emplace_back(pii(S[i].h, tmp[k].second));
178                 G[pii(S[i].h, tmp[k].second)].emplace_back(pii(S[i].h, tmp[k].first));
179             }
180             if(G.size() >= 8 * n) {ok = 0; break;}
181             i = j;
182         }
183         if(!ok) {puts("Oops!"); continue;}
184         S.clear();
185         for(int i = 1; i <= n; ++i) {
186             S.emplace_back(seg{my[i], mx[i], Mx[i], 1});
187             S.emplace_back(seg{My[i], mx[i], Mx[i], -1});
188         }
189         sort(S.begin(), S.end(), cmp1);
190         build(1, 1, b.size());
191         for(int i = 0; i < S.size(); ++i) {
192             if(S[i].o == -1) {
193                 modify(1, 1, b.size(), S[i].l + 1, S[i].r, -1);
194                 continue;
195             }
196             int j = i;
197             while(j + 1 < S.size() && S[j + 1].h == S[j].h && S[j + 1].o == 1) ++j;
198             ret.clear();
199             for(int k = i; k <= j; ++k) {
200                 query(1, 1, b.size(), S[k].l + 1, S[k].r);
201                 modify(1, 1, b.size(), S[k].l + 1, S[k].r, 1);
202             }
203             sort(ret.begin(), ret.end());
204             vector<pii> tmp;
205             for(int k = 0; k < ret.size(); ++k) {
206                 int sz = tmp.size();
207                 if(sz && tmp[sz - 1].second >= ret[k].first) {
208                     ret[k] = pii(tmp[sz - 1].first, ret[k].second);
209                     tmp.pop_back(), tmp.push_back(ret[k]);
210                 }
211                 else tmp.push_back(ret[k]);
212             }
213             for(int k = 0; k < tmp.size(); ++k) {
214                 G[pii(tmp[k].first, S[i].h)].emplace_back(pii(tmp[k].second, S[i].h));
215                 G[pii(tmp[k].second, S[i].h)].emplace_back(pii(tmp[k].first, S[i].h));
216             }
217             if(G.size() >= 8 * n) {ok = 0; break;}
218             i = j;
219         }
220         if(!ok) {puts("Oops!"); continue;}
221         S.clear();
222         for(int i = 1; i <= n; ++i) {
223             S.emplace_back(seg{My[i], mx[i], Mx[i], 1});
224             S.emplace_back(seg{my[i], mx[i], Mx[i], -1});
225         }
226         sort(S.begin(), S.end(), cmp2);
227         build(1, 1, b.size());
228         for(int i = 0; i < S.size(); ++i) {
229             if(S[i].o == -1) {
230                 modify(1, 1, b.size(), S[i].l + 1, S[i].r, -1);
231                 continue;
232             }
233             int j = i;
234             while(j + 1 < S.size() && S[j + 1].h == S[j].h && S[j + 1].o == 1) ++j;
235             ret.clear();
236             for(int k = i; k <= j; ++k) {
237                 query(1, 1, b.size(), S[k].l + 1, S[k].r);
238                 modify(1, 1, b.size(), S[k].l + 1, S[k].r, 1);
239             }
240             sort(ret.begin(), ret.end());
241             vector<pii> tmp;
242             for(int k = 0; k < ret.size(); ++k) {
243                 int sz = tmp.size();
244                 if(sz && tmp[sz - 1].second >= ret[k].first) {
245                     ret[k] = pii(tmp[sz - 1].first, ret[k].second);
246                     tmp.pop_back(), tmp.push_back(ret[k]);
247                 }
248                 else tmp.push_back(ret[k]);
249             }
250             for(int k = 0; k < tmp.size(); ++k) {
251                 G[pii(tmp[k].first, S[i].h)].emplace_back(pii(tmp[k].second, S[i].h));
252                 G[pii(tmp[k].second, S[i].h)].emplace_back(pii(tmp[k].first, S[i].h));
253             }
254             if(G.size() >= 8 * n) {ok = 0; break;}
255             i = j;
256         }
257         if(!ok) {puts("Oops!"); continue;}
258         ans.clear();
259         pii st = (*G.begin()).first;
260         if(G[st].size() != 2) {puts("Oops!"); continue;}
261         if(G[st][0].first == st.first) get(st, G[st][1], st);
262         else get(st, G[st][0], st);
263         if(ans.size() != G.size()) {puts("Oops!"); continue;}
264         printf("%d\n", ans.size());
265         for(int i = 0; i < ans.size(); ++i) printf("%d %d\n", b[ans[i].first], b[ans[i].second]);
266     }
267     return 0;
268 }
Aguin

 

1009 Werewolf

其实窝感觉这题还是有点意思的,就是$Clar$里一堆人不懂题意……

首先第一个数肯定是$0$,就当大家说的都是废话没事发生过

然后铁狼只有唯一的情况,就是某人$A$指认狼$B$,被指认人$B$却通过一串民直接或间接指认$A$为民,那么$B$和所有直接间接指认$B$为民的都是狼

只要对所有指民的边反向建图,以每个指狼的为起点反向随便遍历两边就好了

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 vector<int> G[maxn];
 5 int a[maxn];
 6 
 7 bool dfs(int x, int tar) {
 8     if(x == tar) return true;
 9     for(int i = 0; i < G[x].size(); ++i) {
10         int to = G[x][i];
11         if(dfs(to, tar)) return true;
12     }
13     return false;
14 }
15 
16 int rdfs(int x) {
17     int ret = 1;
18     for(int i = 0; i < G[x].size(); ++i) {
19         int to = G[x][i];
20         ret += rdfs(to);
21     }
22     return ret;
23 }
24 
25 int main() {
26     int T;
27     scanf("%d", &T);
28     while(T--) {
29         int N;
30         scanf("%d", &N);
31         for(int i = 1; i <= N; ++i) G[i].clear();
32         for(int i = 1; i <= N; ++i) {
33             int x;
34             char s[11];
35             scanf("%d %s", &x, s + 1);
36             if(s[1] == 'w') a[i] = x;
37             else {
38                 a[i] = 0;
39                 G[x].push_back(i);
40             }
41         }
42         int ans = 0;
43         for(int i = 1; i <= N; ++i) {
44             if(a[i] == 0) continue;
45             if(dfs(i, a[i])) ans += rdfs(a[i]);
46         }
47         printf("0 %d\n", ans);
48     }
49     return 0;
50 }
Aguin

 

1010 Chopping hands

1011 sacul

1012 Pinball

梦回糕烤

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long T,i,j,k,s;
 4 double a,b,vx,vy,x,y,g=9.8,ans,temp,t,x2,y2,angle1,angle2,vv;
 5 int main()
 6 {
 7         scanf("%lld",&T);
 8         while (T--)
 9         {
10                 scanf("%lf%lf%lf%lf",&a,&b,&x,&y);
11                 angle1=atan(b/a);
12                 vx=vy=0;
13                 s=0;
14                 while (true)
15                 {
16                         t=a*vy+b*vx;
17                         temp=t+sqrt(t*t+2*a*g*(a*y+b*x));
18                         temp=temp/(a*g);
19                         x2=x+vx*temp;y2=y+vy*temp-0.5*g*temp*temp;
20                         if (x2>=0) break; else s++;
21                         vy=vy-temp*g;
22                         angle2=atan(-vx/vy);
23                         temp=acos(-1.0)*0.5-2*angle1-angle2;
24                         vv=sqrt(vx*vx+vy*vy);
25                         vx=vv*cos(temp);
26                         vy=vv*sin(temp);
27                         x=x2;y=y2;
28                 }
29                 printf("%lld\n",s);
30         }
31 }
谈学姐

 

posted @ 2018-08-21 19:14  Aguin  阅读(318)  评论(0编辑  收藏  举报