NOIP2018

好多东西都不熟练……

数论

数论分块「bzoj2956: 模积和

10.28.2018

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 const int MO = 19940417;
 4 const int inv6 = 3323403;
 5 
 6 ll n,m,ans,del;
 7 
 8 inline void Add(ll &x, ll y){x = ((x+y)%MO+MO)%MO;}
 9 ll sum(ll x){return x*(x+1)%MO*(2*x+1)%MO*inv6%MO;}
10 ll calc(ll x)
11 {
12     ll ret = 0;
13     for (ll i=1, j=0; i<=x; i=j+1)
14     {
15         j = x/(x/i);
16         Add(ret, 1ll*(x/i)*(i+j)*(j-i+1)/2%MO);
17     }
18     return ((x%MO*x%MO-ret)+MO)%MO;
19 }
20 int main()
21 {
22     scanf("%lld%lld",&n,&m);
23     if (n > m) std::swap(n, m);
24     ans = calc(n)*calc(m)%MO;
25     del = n*m%MO*n%MO;
26     for (ll i=1, j=0; i<=n; i=j+1)
27     {
28         j = std::min(n/(n/i), m/(m/i));
29         ll s1 = (sum(j)-sum(i-1))*(n/i)%MO*(m/i)%MO;
30         ll s2 = (n*(m/i)%MO+m*(n/i)%MO)%MO*((i+j)*(j-i+1)/2%MO);
31         Add(del, (s1-s2)%MO);
32     }
33     Add(ans, -del);
34     printf("%lld
",ans);
35     return 0;
36 }
View Code

图论

点-树链剖分「1036: [ZJOI2008]树的统计Count」

10.24.2018

  1 #include<bits/stdc++.h>
  2 const int maxn = 30035;
  3 const int maxm = 60035;
  4 const int INF = 0x3f3f3f3f;
  5 
  6 struct node
  7 {
  8     int tot,fa,son,top;
  9 }a[maxn];
 10 int n,m;
 11 char opt[13];
 12 int f[maxn<<2][2];
 13 int chTot,chain[maxn],cnVal[maxn],d[maxn],dep[maxn];
 14 int edgeTot,head[maxn],nxt[maxm],edges[maxm];
 15 
 16 int read()
 17 {
 18     char ch = getchar();
 19     int num = 0;
 20     bool fl = 0;
 21     for (; !isdigit(ch); ch=getchar())
 22         if (ch=='-') fl = 1;
 23     for (; isdigit(ch); ch=getchar())
 24         num = (num<<1)+(num<<3)+ch-48;
 25     if (fl) num = -num;
 26     return num;
 27 }
 28 void addedge(int u, int v)
 29 {
 30     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
 31     edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
 32 }
 33 void pushup(int rt)
 34 {
 35     f[rt][1] = std::max(f[rt<<1][1], f[rt<<1|1][1]);
 36     f[rt][0] = f[rt<<1][0]+f[rt<<1|1][0];
 37 }
 38 void build(int rt, int l, int r)
 39 {
 40     f[rt][1] = -INF;
 41     if (l==r){
 42         f[rt][1] = f[rt][0] = cnVal[l];
 43         return;
 44     }
 45     int mid = (l+r)>>1;
 46     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
 47     pushup(rt);
 48 }
 49 void dfs1(int x, int fa)
 50 {
 51     a[x].fa = fa, a[x].tot = 1;
 52     dep[x] = dep[fa]+1, a[x].son = -1;
 53     for (int i=head[x]; i!=-1; i=nxt[i])
 54     {
 55         int v = edges[i];
 56         if (v!=fa){
 57             dfs1(v, x);
 58             a[x].tot += a[v].tot;
 59             if (a[x].son==-1||a[v].tot > a[a[x].son].tot)
 60                 a[x].son = v;
 61         }
 62     }
 63 }
 64 void dfs2(int x, int top)
 65 {
 66     chain[x] = ++chTot, cnVal[chTot] = d[x], a[x].top = top;
 67     if (a[x].son==-1) return;
 68     dfs2(a[x].son, top);
 69     for (int i=head[x]; i!=-1; i=nxt[i])
 70     {
 71         int v = edges[i];
 72         if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
 73     }
 74 }
 75 void modify(int rt, int l, int r, int pos, int c)
 76 {
 77     if (l==r){
 78         f[rt][0] = f[rt][1] = c;
 79         return;
 80     }
 81     int mid = (l+r)>>1;
 82     if (pos <= mid) modify(rt<<1, l, mid, pos, c);
 83     else modify(rt<<1|1, mid+1, r, pos, c);
 84     pushup(rt);
 85 }
 86 int queryMx(int rt, int L, int R, int l, int r)
 87 {
 88     if (L <= l&&r <= R) return f[rt][1];
 89     int mid = (l+r)>>1, ret = -INF;
 90     if (L <= mid) ret = queryMx(rt<<1, L, R, l, mid);
 91     if (R > mid) ret = std::max(ret, queryMx(rt<<1|1, L, R, mid+1, r));
 92     return ret;
 93 }
 94 int querySm(int rt, int L, int R, int l, int r)
 95 {
 96     if (L <= l&&r <= R) return f[rt][0];
 97     int mid = (l+r)>>1, ret = 0;
 98     if (L <= mid) ret = querySm(rt<<1, L, R, l, mid); 
 99     if (R > mid) ret += querySm(rt<<1|1, L, R, mid+1, r);
100     return ret;
101 }
102 int queryChainMx(int x, int y)
103 {
104     int ret = -INF;
105     while (a[x].top!=a[y].top)
106     {
107         if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
108         ret = std::max(ret, queryMx(1, chain[a[y].top], chain[y], 1, n));
109         y = a[a[y].top].fa;
110     }
111     if (dep[x] > dep[y]) std::swap(x, y);
112     ret = std::max(ret, queryMx(1, chain[x], chain[y], 1, n));
113     return ret;
114 }
115 int queryChainSm(int x, int y)
116 {
117     int ret = 0;
118     while (a[x].top!=a[y].top)
119     {
120         if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
121         ret += querySm(1, chain[a[y].top], chain[y], 1, n);
122         y = a[a[y].top].fa;
123     }
124     if (dep[x] > dep[y]) std::swap(x, y);
125     ret += querySm(1, chain[x], chain[y], 1, n);
126     return ret;
127 }
128 int main()
129 {
130     memset(head, -1, sizeof head);
131     n = read();
132     for (int i=1; i<n; i++) addedge(read(), read());
133     for (int i=1; i<=n; i++) d[i] = read();
134     dfs1(1, 0);
135     dfs2(1, 1);
136     build(1, 1, n);
137     m = read();
138     while (m--)
139     {
140         scanf("%s",opt);
141         int x = read(), y = read();
142         if (opt[0]=='C') modify(1, 1, n, chain[x], y);
143         else if (opt[1]=='M')
144             printf("%d
",queryChainMx(x, y));
145         else printf("%d
",queryChainSm(x, y));
146     }
147     return 0;
148 }

打挂地方已标注。

边-树链剖分「bzoj2238: Mst」

10.28

  1 #include<bits/stdc++.h>
  2 const int maxn = 50035;
  3 const int maxm = 100035;
  4 const int INF = 0x3f3f3f3f;
  5 
  6 struct Edge
  7 {
  8     int u,v,w,id;
  9     bool vis;
 10     Edge(int a=0, int b=0, int c=0):u(a),v(b),w(c) {}
 11 }ev[maxm],edges[maxm];
 12 struct node
 13 {
 14     int tot,son,top,fa;
 15 }a[maxn];
 16 int n,m,q,cnt,ans;
 17 int dep[maxn],fa[maxn],chain[maxn],chTot,f[maxn<<2];
 18 int edgeTot,head[maxn],nxt[maxm];
 19 bool evis[maxm];
 20 
 21 int read()
 22 {
 23     char ch = getchar();
 24     int num = 0;
 25     bool fl = 0;
 26     for (; !isdigit(ch); ch=getchar())
 27         if (ch=='-') fl = 1;
 28     for (; isdigit(ch); ch=getchar())
 29         num = (num<<1)+(num<<3)+ch-48;
 30     if (fl) num = -num;
 31     return num;
 32 }
 33 bool cmp1(Edge a, Edge b)
 34 {
 35     return a.w < b.w;
 36 }
 37 bool cmp2(Edge a, Edge b)
 38 {
 39     return a.id < b.id;
 40 }
 41 int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
 42 void addedge(int u, int v, int c)
 43 {
 44     ans += c, fa[fa[u]] = fa[v];
 45     edges[++edgeTot] = Edge(u, v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
 46     edges[++edgeTot] = Edge(v, u, c), nxt[edgeTot] = head[v], head[v] = edgeTot;
 47 }
 48 void dfs1(int x, int fa)
 49 {
 50     a[x].tot = 1, a[x].son = a[x].top = -1;
 51     a[x].fa = fa, dep[x] = dep[fa]+1;
 52     for (int i=head[x]; i!=-1; i=nxt[i])
 53     {
 54         int v = edges[i].v;
 55         if (v!=fa){
 56             dfs1(v, x), a[x].tot += a[v].tot;
 57             if (a[x].son==-1||a[a[x].son].tot < a[v].tot) a[x].son = v;
 58         }
 59     }
 60 }
 61 void dfs2(int x, int top)
 62 {
 63     a[x].top = top, chain[x] = ++chTot;
 64     if (a[x].son==-1) return;
 65     dfs2(a[x].son, top);
 66     for (int i=head[x]; i!=-1; i=nxt[i])
 67     {
 68         int v = edges[i].v;
 69         if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
 70     }
 71 }
 72 void build(int rt, int l, int r)
 73 {
 74     f[rt] = INF;
 75     if (l==r) return;
 76     int mid = (l+r)>>1;
 77     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
 78 }
 79 void Min(int &x, int y){x = x>y?y:x;}
 80 void pushdown(int rt)
 81 {
 82     Min(f[rt<<1], f[rt]), Min(f[rt<<1|1], f[rt]);
 83 }
 84 void modify(int rt, int L, int R, int l, int r, int c)
 85 {
 86     if (L > R) return;
 87     if (L <= l&&r <= R){
 88         f[rt] = std::min(f[rt], c);
 89         return;
 90     }
 91     int mid = (l+r)>>1;
 92     pushdown(rt);
 93     if (L <= mid) modify(rt<<1, L, R, l, mid, c);
 94     if (R > mid) modify(rt<<1|1, L, R, mid+1, r, c);
 95 }
 96 int query(int rt, int L, int R, int l, int r)
 97 {
 98     if (L > R) return INF;
 99     if (L <= l&&r <= R) return f[rt];
100     int mid = (l+r)>>1, ret = INF;
101     pushdown(rt);
102     if (L <= mid) Min(ret, query(rt<<1, L, R, l, mid));
103     if (R > mid) Min(ret, query(rt<<1|1, L, R, mid+1, r));
104     return ret;
105 }
106 void modifyChain(int x, int y, int c)
107 {
108     while (a[x].top!=a[y].top)
109     {
110         if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
111         modify(1, chain[a[y].top], chain[y], 1, n, c);
112         y = a[a[y].top].fa;
113     }
114     if (dep[x] > dep[y]) std::swap(x, y);
115     modify(1, chain[x]+1, chain[y], 1, n, c);
116 }
117 int queryChain(int x, int y)
118 {
119     int ret = INF;
120     while (a[x].top!=a[y].top)
121     {
122         if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
123         Min(ret, query(1, chain[a[y].top], chain[y], 1, n));
124         y = a[a[y].top].fa;
125     }
126     if (dep[x] > dep[y]) std::swap(x, y);
127     Min(ret, query(1, chain[x]+1, chain[y], 1, n));
128     return ret;
129 }
130 int main()
131 {
132     memset(head, -1, sizeof head);
133     n = read(), m = read();
134     for (int i=1; i<=n; i++) fa[i] = i;
135     for (int i=1; i<=m; i++)
136         ev[i].u = read(), ev[i].v = read(), ev[i].w = read(), ev[i].id = i;
137     std::sort(ev+1, ev+m+1, cmp1);
138     for (int i=1; i<=m; i++)
139         if (get(ev[i].u)!=get(ev[i].v)){
140             int u = ev[i].u, v = ev[i].v;
141             ev[i].vis = evis[ev[i].id] = 1, cnt++, addedge(u, v, ev[i].w);
142             if (cnt==n-1) break;
143         }
144     if (cnt!=n-1){
145         q = read();
146         while (q--) puts("Not connected");
147         return 0;
148     }
149     dfs1(1, 0);
150     dfs2(1, 1);
151     build(1, 1, n);
152     for (int i=m; i; i--)
153         if (!ev[i].vis) modifyChain(ev[i].u, ev[i].v, ev[i].w);
154     std::sort(ev+1, ev+m+1, cmp2);
155     for (q=read(); q; q--)
156     {
157         int cse = read();
158         if (!evis[cse]) printf("%d
",ans);
159         else{
160             int cnt = queryChain(ev[cse].u, ev[cse].v);
161             if (cnt!=INF) printf("%d
",ans-ev[cse].w+cnt);
162             else puts("Not connected");
163         }
164     }
165     return 0;
166 }
View Code

evis开成maxn一发RE

SPFA负权环「bzoj1715: [Usaco2006 Dec]Wormholes 虫洞」

10.24.2018

 1 #include<bits/stdc++.h>
 2 const int maxn = 503;
 3 const int maxm = 6003;
 4 
 5 struct Edge
 6 {
 7     int y,val;
 8     Edge(int a=0, int b=0):y(a),val(b) {}
 9 }edges[maxm];
10 int T,n,m,w;
11 bool vis[maxn];
12 int dis[maxn],edgeTot,head[maxn],nxt[maxm];
13 
14 int read()
15 {
16     char ch = getchar();
17     int num = 0;
18     bool fl = 0;
19     for (; !isdigit(ch); ch=getchar())
20         if (ch=='-') fl = 1;
21     for (; isdigit(ch); ch=getchar())
22         num = (num<<1)+(num<<3)+ch-48;
23     if (fl) num = -num;
24     return num;
25 }
26 void addedge(int u, int v, int c)
27 {
28     edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
29 }
30 bool dfs(int x)
31 {
32     vis[x] = 1;
33     for (int i=head[x]; i!=-1; i=nxt[i])
34     {
35         int v = edges[i].y;
36         if (dis[v] > dis[x]+edges[i].val){
37             dis[v] = dis[x]+edges[i].val;
38             if (vis[v]||dfs(v)){
39                 vis[x] = 0;
40                 return 1;
41             }
42         }
43     }
44     vis[x] = 0;
45     return 0;
46 }
47 int main()
48 {
49     T = read();
50     while (T--)
51     {
52         memset(head, -1, sizeof head);
53         memset(dis, 0, sizeof dis);
54         edgeTot = 0, n = read(), m = read(), w = read();
55         for (int i=1; i<=m; i++)
56         {
57             int u = read(), v = read(), c = read();
58             addedge(u, v, c), addedge(v, u, c);
59         }
60         for (int i=1; i<=w; i++)
61         {
62             int u = read(), v = read(), c = read();
63             addedge(u, v, -c);
64         }
65         bool fl = 0;
66         for (int i=1; i<=n; i++)
67             if (dfs(i)){
68                 puts("YES"), fl = 1;
69                 break;
70             }
71         if (!fl) puts("NO");        
72     }
73     return 0;
74 }
View Code

差分约束「poj1201Intervals」

10.26.2018

这个和线性规划相比,要把式子全都化成三角形不等式的形式。

所以小于等于或者大于等于的两种情况自己注意。

 1 #include<bits/stdc++.h>
 2 const int maxn = 50035;
 3 const int maxm = 200035;
 4 
 5 struct Edge
 6 {
 7     int y,val;
 8     Edge(int a=0, int b=0):y(a),val(b) {}
 9 }edges[maxm];
10 int n,mx;
11 bool stk[maxn];
12 std::queue<int> q;
13 int dis[maxn],vis[maxn];
14 int edgeTot,head[maxn],nxt[maxm];
15 
16 int read()
17 {
18     char ch = getchar();
19     int num = 0;
20     bool fl = 0;
21     for (; !isdigit(ch); ch=getchar())
22         if (ch=='-') fl = 1;
23     for (; isdigit(ch); ch=getchar())
24         num = (num<<1)+(num<<3)+ch-48;
25     if (fl) num = -num;
26     return num;
27 }
28 void addedge(int u, int v, int c)
29 {
30     edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
31 }
32 void spfa()
33 {
34     memset(dis, -0x3f3f3f3f, sizeof dis);
35     dis[0] = 0, q.push(0);
36     while (q.size())
37     {
38         int tt = q.front();
39         q.pop(), stk[tt] = 0;
40         for (int i=head[tt]; i!=-1; i=nxt[i])
41         {
42             int v = edges[i].y, w = edges[i].val;
43             if (dis[v] < dis[tt]+w){
44                 dis[v] = dis[tt]+w;
45                 if (!stk[v]) stk[v] = 1, q.push(v);
46             }
47         }
48     }
49 }
50 int main()
51 {
52     memset(head, -1, sizeof head);
53     n = read();
54     for (int i=1; i<=n; i++)
55     {
56         int a = read()+1, b = read()+1, c = read();
57         mx = std::max(mx, b);
58         addedge(a-1, b, c);
59     }
60     for (int i=0; i<mx; i++) addedge(i, i+1, 0), addedge(i+1, i, -1);
61     spfa();
62     printf("%d
",dis[mx]);
63     return 0;
64 }
 1 #include<bits/stdc++.h>
 2 const int maxn = 50035;
 3 const int maxm = 200035;
 4 
 5 struct Edge
 6 {
 7     int y,val;
 8     Edge(int a=0, int b=0):y(a),val(b) {}
 9 }edges[maxm];
10 int n,mx;
11 bool stk[maxn];
12 std::queue<int> q;
13 int dis[maxn],vis[maxn];
14 int edgeTot,head[maxn],nxt[maxm];
15 
16 int read()
17 {
18     char ch = getchar();
19     int num = 0;
20     bool fl = 0;
21     for (; !isdigit(ch); ch=getchar())
22         if (ch=='-') fl = 1;
23     for (; isdigit(ch); ch=getchar())
24         num = (num<<1)+(num<<3)+ch-48;
25     if (fl) num = -num;
26     return num;
27 }
28 void addedge(int u, int v, int c)
29 {
30     edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
31 }
32 void spfa()
33 {
34     memset(dis, 0x3f3f3f3f, sizeof dis);
35     dis[mx] = 0, q.push(mx);
36     while (q.size())
37     {
38         int tt = q.front();
39         q.pop(), stk[tt] = 0;
40         for (int i=head[tt]; i!=-1; i=nxt[i])
41         {
42             int v = edges[i].y, w = edges[i].val;
43             if (dis[v] > dis[tt]+w){
44                 dis[v] = dis[tt]+w;
45                 if (!stk[v]) stk[v] = 1, q.push(v);
46             }
47         }
48     }
49 }
50 int main()
51 {
52     memset(head, -1, sizeof head);
53     n = read();
54     for (int i=1; i<=n; i++)
55     {
56         int a = read()+1, b = read()+1, c = read();
57         mx = std::max(mx, b);
58         addedge(b, a-1, -c);
59     }
60     for (int i=0; i<mx; i++) addedge(i, i+1, 1), addedge(i+1, i, 0);
61     spfa();
62     printf("%d
",-dis[0]);
63     return 0;
64 }

点树上差分「bzoj4390: [Usaco2015 dec]Max Flow」

11.5.2018

 1 #include<bits/stdc++.h>
 2 const int maxn = 50035;
 3 const int maxm = 100035;
 4 const int maxLog = 23;
 5 
 6 int n,m;
 7 int f[maxn][maxLog],sum[maxn],ans;
 8 int edgeTot,head[maxn],edges[maxm],nxt[maxm],dep[maxn];
 9 
10 int read()
11 {
12     char ch = getchar();
13     int num = 0;
14     bool fl = 0;
15     for (; !isdigit(ch); ch=getchar())
16         if (ch=='-') fl = 1;
17     for (; isdigit(ch); ch=getchar())
18         num = (num<<1)+(num<<3)+ch-48;
19     if (fl) num = -num;
20     return num;
21 }
22 void addedge(int u, int v)
23 {
24     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
25     edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
26 }
27 void dfs(int x, int fa)
28 {
29     f[x][0] = fa, dep[x] = dep[fa]+1;
30     for (int i=head[x]; i!=-1; i=nxt[i])
31         if (edges[i]!=fa) dfs(edges[i], x);
32 }
33 int lca(int u, int v)
34 {
35     if (dep[u] > dep[v]) std::swap(u, v);
36     for (int i=20; i>=0; i--)
37         if (dep[u] <= dep[v]-(1<<i))
38             v = f[v][i];
39     if (u==v) return u;
40     for (int i=20; i>=0; i--)
41         if (f[u][i]!=f[v][i])
42             u = f[u][i], v = f[v][i];
43     return f[u][0];
44 }
45 void fnd(int x)
46 {
47     for (int i=head[x]; i!=-1; i=nxt[i])
48         if (edges[i]!=f[x][0])
49             fnd(edges[i]), sum[x] += sum[edges[i]];
50     if (ans < sum[x]) ans = sum[x];
51 }
52 int main()
53 {
54     memset(head, -1, sizeof head);
55     n = read(), m = read();
56     for (register int i=1; i<n; i++) addedge(read(), read());
57     dfs(1, 0);
58     for (register int j=1; j<=20; j++)
59         for (register int i=1; i<=n; i++)
60             f[i][j] = f[f[i][j-1]][j-1];
61     for (register int i=1; i<=m; i++)
62     {
63         register int u = read(), v = read(), ger = lca(u, v);
64         sum[u]++, sum[v]++, sum[ger]--, sum[f[ger][0]]--;
65     }
66     fnd(1);
67     printf("%d
",ans);
68     return 0;
69 }
View Code
原文地址:https://www.cnblogs.com/antiquality/p/9841127.html