蒟蒻的bzoj小结
NOI2013,终于还是退役了。。。就把我在bzoj上刷过的水题贴上来吧,为了造(bao)福(fu)社会
大家千万不要学习我那个蛋疼的不用stl容器的习惯(除非你们省选和电子坑大一样是用cena和cena自带的编译器来评测的。。。)
bzoj1000
神题不会
bzoj1001
正解应该是平面图最小割转最短路,然后我会说网络流跑得飞快?
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxm 1000010 8 #define inf 0x3f3f3f3f 9 10 struct edge 11 { 12 int flow,to; 13 edge *next,*part; 14 }e[maxm<<3],*head[maxm]; 15 16 int ne=0,s=1,t; 17 int q[maxm],d[maxm]; 18 19 inline void add(int from,int to,int flow) 20 { 21 e[ne].to=to; 22 e[ne].flow=flow; 23 e[ne].next=head[from]; 24 head[from]=&e[ne++]; 25 } 26 27 inline void add_edge(int from,int to,int flow) 28 { 29 e[ne].part=&e[ne+1]; 30 e[ne+1].part=&e[ne]; 31 add(from,to,flow); 32 add(to,from,flow); 33 } 34 35 inline bool bfs() 36 { 37 memset(d,-1,sizeof(d)); 38 int op=0,cls=1; 39 q[1]=s; 40 d[s]=1; 41 edge *p; 42 while (op != cls) 43 { 44 int x=q[++op]; 45 for (p=head[x];p;p=p->next) 46 if (p->flow && d[p->to] == -1) 47 { 48 d[p->to]=d[x]+1; 49 q[++cls]=p->to; 50 } 51 } 52 return d[t] != -1; 53 } 54 55 int dfs(int now,int now_flow) 56 { 57 if (now == t) 58 return now_flow; 59 int out=now_flow; 60 edge *p; 61 for (p=head[now];p;p=p->next) 62 if (p->flow && d[p->to] == d[now]+1 && out) 63 { 64 int flow=dfs(p->to,min(p->flow,out)); 65 p->flow-=flow; 66 p->part->flow+=flow; 67 out-=flow; 68 } 69 if (out == now_flow) 70 d[now]=-1; 71 return now_flow-out; 72 } 73 74 inline void dinic() 75 { 76 int ans=0; 77 while (bfs()) 78 ans+=dfs(s,inf); 79 printf("%d\n",ans); 80 } 81 82 inline void read(int &x) 83 { 84 char ch; 85 while (ch=getchar(),ch > '9' || ch < '0'); 86 x=ch-'0'; 87 while (ch=getchar(),ch <= '9' && ch >= '0') 88 x=(x<<3)+x+x+ch-'0'; 89 } 90 91 inline bool init() 92 { 93 int n,m,x; 94 read(n); 95 read(m); 96 if (n == 1) 97 { 98 int ans=inf; 99 for (int i=1;i<m;i++) 100 { 101 read(x); 102 ans=min(ans,x); 103 } 104 printf("%d\n",ans); 105 return 0; 106 } 107 else 108 { 109 if (m == 1) 110 { 111 int ans=inf; 112 for (int i=1;i<n;i++) 113 { 114 read(x); 115 ans=min(ans,x); 116 } 117 printf("%d",ans); 118 return 0; 119 } 120 else 121 { 122 t=n*m; 123 for (int i=1;i<=n;i++) 124 for (int j=1;j<m;j++) 125 { 126 read(x); 127 add_edge((i-1)*m+j,(i-1)*m+j+1,x); 128 } 129 for (int i=1;i<n;i++) 130 for (int j=1;j<=m;j++) 131 { 132 read(x); 133 add_edge((i-1)*m+j,i*m+j,x); 134 } 135 for (int i=1;i<n;i++) 136 for (int j=1;j<m;j++) 137 { 138 read(x); 139 add_edge((i-1)*m+j,i*m+j+1,x); 140 } 141 return 1; 142 } 143 } 144 } 145 146 int main() 147 { 148 if (init()) 149 dinic(); 150 return 0; 151 }
bzoj1002
裸高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #ifdef unix 11 #define ll "%lld" 12 #else 13 #define ll "%I64d" 14 #endif 15 class wkint { 16 private: 17 long long a[1510]; 18 int len; 19 public: 20 wkint(); 21 wkint(int t); 22 void read(); 23 void print(); 24 wkint operator + (const wkint &t) const; 25 wkint operator - (const wkint &t) const; 26 wkint operator * (const wkint &t) const; 27 wkint operator * (const int &t) const; 28 wkint operator ^ (const int &t) const; 29 wkint operator / (const int &t) const; 30 int operator % (const int &t) const; 31 bool operator < (const wkint &t) const; 32 bool operator > (const wkint &t) const; 33 bool operator == (const wkint &t) const; 34 bool operator != (const wkint &t) const; 35 }; 36 37 wkint::wkint() { 38 len = 1; 39 memset(a, 0, sizeof(a)); 40 } 41 wkint::wkint(int t) { 42 len = 1; 43 a[1] = t; 44 } 45 void wkint::read() { 46 string tmp; 47 cin >> tmp; 48 int lenT = tmp.length(); 49 len = (lenT + 7) / 8; 50 int ptr = len, now = 0; 51 for (int i = 0; i < lenT; i ++) { 52 now *= 10; now += (int)(tmp[i] - '0'); 53 if (!((lenT - i - 1) % 8)) { 54 a[ptr] = now; 55 now = 0; 56 ptr --; 57 } 58 } 59 } 60 void wkint::print() { 61 printf(ll, a[len]); 62 for (int i = len - 1; i >= 1; i --) { 63 int ws = (int)log10((long double)(a[i] + 1)) + 1; 64 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 65 printf(ll, a[i]); 66 } 67 printf("\n"); 68 } 69 wkint wkint::operator + (const wkint &t) const { 70 wkint res; 71 int maxlen = max(t.len, len); 72 for (int i = 1; i <= maxlen; i ++) { 73 res.a[i] += a[i] + t.a[i]; 74 if (res.a[i] >= 100000000) { 75 res.a[i + 1] += res.a[i] / 100000000; 76 res.a[i] %= 100000000; 77 } 78 } 79 if (res.a[maxlen + 1]) maxlen ++; 80 res.len = maxlen; 81 return res; 82 } 83 wkint wkint::operator - (const wkint &t) const { 84 wkint res; 85 int maxlen = max(t.len, len); 86 for (int i = 1; i <= maxlen; i ++) { 87 res.a[i] += a[i] - t.a[i]; 88 if (res.a[i] < 0) { 89 res.a[i + 1] -= 1; 90 res.a[i] += 100000000; 91 } 92 } 93 while (!res.a[maxlen]) maxlen --; 94 res.len = maxlen; 95 return res; 96 } 97 wkint wkint::operator * (const wkint &t) const { 98 wkint res; 99 int maxlen = t.len + len - 1; 100 for (int i = 1; i <= len; i ++) 101 for (int j = 1; j <= t.len; j ++) { 102 res.a[i + j - 1] += a[i] * t.a[j]; 103 } 104 for (int i = 1; i <= maxlen; i ++) 105 if (res.a[i] > 100000000) { 106 res.a[i + 1] += res.a[i] / 100000000; 107 res.a[i] %= 100000000; 108 } 109 if (res.a[maxlen + 1]) maxlen ++; 110 res.len = maxlen; 111 return res; 112 } 113 wkint wkint::operator * (const int &t) const { 114 wkint res; 115 res.len = len; 116 for (int i = 1; i <= len; i ++) { 117 res.a[i] += a[i] * t; 118 if (res.a[i] > 100000000) { 119 res.a[i + 1] += res.a[i] / 100000000; 120 res.a[i] %= 100000000; 121 } 122 } 123 if (res.a[res.len + 1]) res.len ++; 124 return res; 125 } 126 wkint wkint::operator ^ (const int &t) const { 127 wkint res = wkint(1), tmp; 128 int now = t; 129 memcpy(tmp.a, a, sizeof(a)); 130 tmp.len = len; 131 while (now) { 132 if (now & 1) res = res * tmp; 133 tmp = tmp * tmp; 134 now >>= 1; 135 } 136 return res; 137 } 138 wkint wkint::operator / (const int &t) const { 139 wkint res; 140 long long now = 0; 141 res.len = len; 142 for (int i = len; i >= 1; i --) { 143 now *= 100000000, now += a[i]; 144 if (now < t) { 145 res.a[i] = 0; 146 } else { 147 res.a[i] = now / t; 148 now %= t; 149 } 150 } 151 while (!res.a[res.len]) res.len --; 152 return res; 153 } 154 int wkint::operator % (const int &t) const { 155 long long now = 0; 156 for (int i = len; i >= 1; i --) { 157 now *= 100000000, now += a[i]; 158 now %= t; 159 } 160 return (int)now; 161 } 162 bool wkint::operator < (const wkint &t) const { 163 if (len < t.len) return true; 164 if (len > t.len) return false; 165 for (int i = len; i >= 1; i --) 166 if (a[i] < t.a[i]) { 167 return true; 168 } else if (a[i] > t.a[i]) { 169 return false; 170 } 171 return false; 172 } 173 bool wkint::operator > (const wkint &t) const { 174 if (len > t.len) return true; 175 if (len < t.len) return false; 176 for (int i = len; i >= 1; i --) 177 if (a[i] > t.a[i]) { 178 return true; 179 } else if (a[i] < t.a[i]) { 180 return false; 181 } 182 return false; 183 } 184 bool wkint::operator == (const wkint &t) const { 185 if (t.len != len) return false; 186 for (int i = 1; i <= len; i ++) 187 if (a[i] != t.a[i]) { 188 return false; 189 } 190 return true; 191 } 192 bool wkint::operator != (const wkint &t) const { 193 if (t.len != len) return true; 194 for (int i = 1; i <= len; i ++) 195 if (a[i] != t.a[i]) { 196 return true; 197 } 198 return false; 199 } 200 201 wkint ans[101]; 202 203 int main() 204 { 205 int n; 206 scanf("%d",&n); 207 ans[1]=1; 208 ans[2]=5; 209 for (int i=3;i<=n;i++) 210 ans[i]=ans[i-1]+ans[i-1]+ans[i-1]-ans[i-2]+2; 211 ans[n].print(); 212 return 0; 213 }
bzoj1003
预处理两天之间的最短路,然后DP
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 30 5 #define maxt 110 6 #define maxm 610 7 #define inf 0x3f3f3f3f 8 9 struct edge 10 { 11 int to,dist; 12 edge *next; 13 }e[maxm],*head[maxn]; 14 15 int n; 16 int ne=0; 17 int q[maxn],d[maxn]; 18 bool flag[maxn],vis[maxn]; 19 20 inline int min(int a,int b) 21 { 22 return a < b ? a : b; 23 } 24 25 inline int spfa() 26 { 27 memset(d,0x3f,sizeof(d)); 28 memset(vis,0,sizeof(vis)); 29 int op=0,cls=1; 30 q[1]=1; 31 d[1]=0; 32 vis[1]=1; 33 while (op != cls) 34 { 35 op=op == maxn-1 ? 0 : op+1; 36 int x=q[op]; 37 for (edge *p=head[x];p;p=p->next) 38 if (flag[p->to] && d[p->to] > d[x]+p->dist) 39 { 40 d[p->to]=d[x]+p->dist; 41 if (!vis[p->to]) 42 { 43 if (op != cls) 44 { 45 int now=op == maxn-1 ? 0 : op+1; 46 if (d[p->to] < d[now]) 47 { 48 q[op]=p->to; 49 op=op ? op-1 : maxn-1; 50 } 51 else 52 { 53 cls=cls == maxn-1 ? 0 : cls+1; 54 q[cls]=p->to; 55 } 56 } 57 else 58 { 59 cls=cls == maxn-1 ? 0 : cls+1; 60 q[cls]=p->to; 61 } 62 } 63 } 64 vis[x]=0; 65 } 66 return d[n]; 67 } 68 69 inline void add_edge(int from,int to,int dist) 70 { 71 e[ne].to=to; 72 e[ne].dist=dist; 73 e[ne].next=head[from]; 74 head[from]=&e[ne++]; 75 } 76 77 int f[maxt]; 78 int cost[maxt][maxt]; 79 bool acc[maxn][maxt]; 80 81 int main() 82 { 83 int t,m,k; 84 scanf("%d%d%d%d",&t,&n,&k,&m); 85 for (int i=1;i<=m;i++) 86 { 87 int x,y,z; 88 scanf("%d%d%d",&x,&y,&z); 89 add_edge(x,y,z); 90 add_edge(y,x,z); 91 } 92 int _; 93 scanf("%d",&_); 94 memset(acc,1,sizeof(acc)); 95 while (_--) 96 { 97 int x,y,z; 98 scanf("%d%d%d",&x,&y,&z); 99 for (int i=y;i<=z;i++) 100 acc[x][i]=0; 101 } 102 for (int i=1;i<=t;i++) 103 { 104 memset(flag,1,sizeof(flag)); 105 for (int j=i;j<=t;j++) 106 { 107 for (int k=2;k<n;k++) 108 if (!acc[k][j]) 109 flag[k]=0; 110 cost[i][j]=spfa(); 111 } 112 } 113 for (int i=1;i<=t;i++) 114 if (cost[1][i] == inf) 115 f[i]=inf; 116 else 117 f[i]=cost[1][i]*i; 118 for (int i=2;i<=t;i++) 119 for (int j=1;j<i;j++) 120 if (cost[j+1][i] != inf) 121 f[i]=min(f[i],f[j]+cost[j+1][i]*(i-j)+k); 122 printf("%d\n",f[t]); 123 return 0; 124 }
bzoj1005
prufer编码+高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #define maxn 1010 11 12 #ifdef unix 13 #define ll "%lld" 14 #else 15 #define ll "%I64d" 16 #endif 17 class wkint { 18 private: 19 long long a[1510]; 20 int len; 21 public: 22 wkint(); 23 wkint(int t); 24 void read(); 25 void print(); 26 wkint operator + (const wkint &t) const; 27 wkint operator - (const wkint &t) const; 28 wkint operator * (const wkint &t) const; 29 wkint operator * (const int &t) const; 30 wkint operator ^ (const int &t) const; 31 wkint operator / (const int &t) const; 32 int operator % (const int &t) const; 33 bool operator < (const wkint &t) const; 34 bool operator > (const wkint &t) const; 35 bool operator == (const wkint &t) const; 36 bool operator != (const wkint &t) const; 37 }; 38 39 wkint::wkint() { 40 len = 1; 41 memset(a, 0, sizeof(a)); 42 } 43 wkint::wkint(int t) { 44 len = 1; 45 a[1] = t; 46 } 47 void wkint::read() { 48 string tmp; 49 cin >> tmp; 50 int lenT = tmp.length(); 51 len = (lenT + 7) / 8; 52 int ptr = len, now = 0; 53 for (int i = 0; i < lenT; i ++) { 54 now *= 10; now += (int)(tmp[i] - '0'); 55 if (!((lenT - i - 1) % 8)) { 56 a[ptr] = now; 57 now = 0; 58 ptr --; 59 } 60 } 61 } 62 void wkint::print() { 63 printf(ll, a[len]); 64 for (int i = len - 1; i >= 1; i --) { 65 int ws = (int)log10((long double)(a[i] + 1)) + 1; 66 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 67 printf(ll, a[i]); 68 } 69 printf("\n"); 70 } 71 wkint wkint::operator + (const wkint &t) const { 72 wkint res; 73 int maxlen = max(t.len, len); 74 for (int i = 1; i <= maxlen; i ++) { 75 res.a[i] += a[i] + t.a[i]; 76 if (res.a[i] >= 100000000) { 77 res.a[i + 1] += res.a[i] / 100000000; 78 res.a[i] %= 100000000; 79 } 80 } 81 if (res.a[maxlen + 1]) maxlen ++; 82 res.len = maxlen; 83 return res; 84 } 85 wkint wkint::operator - (const wkint &t) const { 86 wkint res; 87 int maxlen = max(t.len, len); 88 for (int i = 1; i <= maxlen; i ++) { 89 res.a[i] += a[i] - t.a[i]; 90 if (res.a[i] < 0) { 91 res.a[i + 1] -= 1; 92 res.a[i] += 100000000; 93 } 94 } 95 while (!res.a[maxlen]) maxlen --; 96 res.len = maxlen; 97 return res; 98 } 99 wkint wkint::operator * (const wkint &t) const { 100 wkint res; 101 int maxlen = t.len + len - 1; 102 for (int i = 1; i <= len; i ++) 103 for (int j = 1; j <= t.len; j ++) { 104 res.a[i + j - 1] += a[i] * t.a[j]; 105 } 106 for (int i = 1; i <= maxlen; i ++) 107 if (res.a[i] > 100000000) { 108 res.a[i + 1] += res.a[i] / 100000000; 109 res.a[i] %= 100000000; 110 } 111 if (res.a[maxlen + 1]) maxlen ++; 112 res.len = maxlen; 113 return res; 114 } 115 wkint wkint::operator * (const int &t) const { 116 wkint res; 117 res.len = len; 118 for (int i = 1; i <= len; i ++) { 119 res.a[i] += a[i] * t; 120 if (res.a[i] > 100000000) { 121 res.a[i + 1] += res.a[i] / 100000000; 122 res.a[i] %= 100000000; 123 } 124 } 125 if (res.a[res.len + 1]) res.len ++; 126 return res; 127 } 128 wkint wkint::operator ^ (const int &t) const { 129 wkint res = wkint(1), tmp; 130 int now = t; 131 memcpy(tmp.a, a, sizeof(a)); 132 tmp.len = len; 133 while (now) { 134 if (now & 1) res = res * tmp; 135 tmp = tmp * tmp; 136 now >>= 1; 137 } 138 return res; 139 } 140 wkint wkint::operator / (const int &t) const { 141 wkint res; 142 long long now = 0; 143 res.len = len; 144 for (int i = len; i >= 1; i --) { 145 now *= 100000000, now += a[i]; 146 if (now < t) { 147 res.a[i] = 0; 148 } else { 149 res.a[i] = now / t; 150 now %= t; 151 } 152 } 153 while (!res.a[res.len]) res.len --; 154 return res; 155 } 156 int wkint::operator % (const int &t) const { 157 long long now = 0; 158 for (int i = len; i >= 1; i --) { 159 now *= 100000000, now += a[i]; 160 now %= t; 161 } 162 return (int)now; 163 } 164 bool wkint::operator < (const wkint &t) const { 165 if (len < t.len) return true; 166 if (len > t.len) return false; 167 for (int i = len; i >= 1; i --) 168 if (a[i] < t.a[i]) { 169 return true; 170 } else if (a[i] > t.a[i]) { 171 return false; 172 } 173 return false; 174 } 175 bool wkint::operator > (const wkint &t) const { 176 if (len > t.len) return true; 177 if (len < t.len) return false; 178 for (int i = len; i >= 1; i --) 179 if (a[i] > t.a[i]) { 180 return true; 181 } else if (a[i] < t.a[i]) { 182 return false; 183 } 184 return false; 185 } 186 bool wkint::operator == (const wkint &t) const { 187 if (t.len != len) return false; 188 for (int i = 1; i <= len; i ++) 189 if (a[i] != t.a[i]) { 190 return false; 191 } 192 return true; 193 } 194 bool wkint::operator != (const wkint &t) const { 195 if (t.len != len) return true; 196 for (int i = 1; i <= len; i ++) 197 if (a[i] != t.a[i]) { 198 return true; 199 } 200 return false; 201 } 202 203 int d[maxn]; 204 205 int main() 206 { 207 int n; 208 scanf("%d",&n); 209 int cnt=0,sum=0; 210 for (int i=1;i<=n;i++) 211 { 212 scanf("%d",&d[i]); 213 if (d[i] == -1) 214 cnt++; 215 else 216 { 217 d[i]--; 218 sum+=d[i]; 219 } 220 } 221 wkint ans=1; 222 for (int i=1;i<=n-2-sum;i++) 223 ans=ans*cnt; 224 for (int i=n-1-sum;i<=n-2;i++) 225 ans=ans*i; 226 for (int i=1;i<=n;i++) 227 if (d[i] != -1) 228 for (int j=1;j<=d[i];j++) 229 ans=ans/j; 230 ans.print(); 231 return 0; 232 }
bzoj1006
弦图的完美消除序列,可以参考cdq的论文
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 10010 5 #define maxm 1000010 6 7 struct edge 8 { 9 int to; 10 edge *next; 11 }e[maxm<<1],*head[maxn]; 12 13 int ne=0; 14 15 inline void add_edge(int from,int to) 16 { 17 e[ne].to=to; 18 e[ne].next=head[from]; 19 head[from]=&e[ne++]; 20 } 21 22 inline void read(int &x) 23 { 24 char ch; 25 while (ch=getchar(),ch > '9' || ch < '0'); 26 x=ch-'0'; 27 while (ch=getchar(),ch <= '9' && ch >= '0') 28 x=(x<<3)+x+x+ch-'0'; 29 } 30 31 int d[maxn],col[maxn],a[maxn]; 32 int sta[maxn]; 33 bool flag[maxn]; 34 35 int main() 36 { 37 int n,m; 38 read(n); 39 read(m); 40 for (int i=1;i<=m;i++) 41 { 42 int x,y; 43 read(x); 44 read(y); 45 add_edge(x,y); 46 add_edge(y,x); 47 } 48 d[0]=-1; 49 for (int i=n;i;i--) 50 { 51 int now=0; 52 for (int j=1;j<=n;j++) 53 if (!flag[j] && d[j] > d[now]) 54 now=j; 55 flag[now]=1; 56 a[i]=now; 57 for (edge *p=head[now];p;p=p->next) 58 d[p->to]++; 59 } 60 int ans=0; 61 int top=1; 62 memset(flag,0,sizeof(flag)); 63 for (int i=n;i;i--) 64 { 65 int x=a[i]; 66 for (edge *p=head[x];p;p=p->next) 67 { 68 sta[++top]=col[p->to]; 69 flag[col[p->to]]=1; 70 } 71 int now; 72 for (now=1;flag[now];now++); 73 col[x]=now; 74 if (now > ans) 75 ans=now; 76 while (top) 77 flag[sta[top--]]=0; 78 } 79 printf("%d\n",ans); 80 return 0; 81 }
bzoj1007
半平面交,按斜率排序之后开个栈扫一遍
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 50010 8 #define eps 1e-6 9 10 struct line 11 { 12 int k,b,num; 13 14 inline bool operator < (const line x) const 15 { 16 return (k < x.k) || (k == x.k && b > x.b); 17 } 18 }a[maxn]; 19 20 inline void read(int &x) 21 { 22 char ch; 23 bool flag=0; 24 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-')); 25 if (ch == '-') 26 flag=1; 27 else 28 x=ch-'0'; 29 while (ch=getchar(),ch <= '9' && ch >= '0') 30 x=(x<<3)+x+x+ch-'0'; 31 if (flag) 32 x=-x; 33 } 34 35 inline double point(int x,int y) 36 { 37 return (double)(a[y].b-a[x].b)/(a[x].k-a[y].k); 38 } 39 40 int sta[maxn]; 41 int ans[maxn]; 42 43 int main() 44 { 45 int n; 46 read(n); 47 if (n == 1) 48 { 49 puts("1"); 50 return 0; 51 } 52 for (int i=1;i<=n;i++) 53 { 54 read(a[i].k); 55 read(a[i].b); 56 a[i].num=i; 57 } 58 sort(a+1,a+n+1); 59 int top=1; 60 sta[top]=1; 61 for (int i=2;i<=n;i++) 62 { 63 if (a[i].k != a[i-1].k) 64 break; 65 if (i == n) 66 { 67 printf("%d ",a[1].num); 68 return 0; 69 } 70 } 71 for (int i=2;i<=n;i++) 72 { 73 if (a[i].k == a[sta[top]].k) 74 continue; 75 if (top < 2) 76 sta[++top]=i; 77 else 78 { 79 while (top >= 2 && point(sta[top],i) <= point(sta[top-1],sta[top])) 80 top--; 81 sta[++top]=i; 82 } 83 } 84 for (int i=1;i<=top;i++) 85 ans[i]=a[sta[i]].num; 86 sort(ans+1,ans+top+1); 87 for (int i=1;i<=top;i++) 88 printf("%d ",ans[i]); 89 return 0; 90 }
bzoj1008
写出DP方程(我这个蒟蒻才会干这种事。。。)然后找规律快速幂
1 #include <cstdio> 2 3 #define mod 100003LL 4 5 #ifdef unix 6 #define LL "%lld" 7 #else 8 #define LL "%I64d" 9 #endif 10 11 long long n,m; 12 13 inline long long calc(long long a,long long b) 14 { 15 long long ans=1,wk=a; 16 while (b) 17 { 18 if (b & 1) 19 (ans*=wk)%=mod; 20 (wk*=wk)%=mod; 21 b>>=1; 22 } 23 return ans; 24 } 25 26 int main() 27 { 28 scanf(LL LL,&m,&n); 29 long long ans=calc(m,n)-(calc(m-1,n-1)*m)%mod; 30 if (ans < 0) 31 ans+=mod; 32 printf(LL,ans); 33 return 0; 34 }
bzoj1009
KMP之后DP,需要矩阵快速幂优化,由于我太弱了不会KMP就只有写AC自动机了
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 30 5 6 struct Node 7 { 8 Node *s[10]; 9 Node *fail; 10 }t[maxn],*root,*q[maxn]; 11 12 int ne=1; 13 char s[maxn]; 14 15 inline void insert(char* str) 16 { 17 int l=strlen(str); 18 Node* now=root; 19 for (int i=0;i<l;i++) 20 { 21 char p=str[i]-'0'; 22 if (now->s[p] == NULL) 23 now->s[p]=&t[++ne]; 24 now=now->s[p]; 25 } 26 } 27 28 inline void build() 29 { 30 for (int i=0;i<10;i++) 31 if (root->s[i] == NULL) 32 root->s[i]=root; 33 int op=0,cls=1; 34 q[1]=root; 35 while (op != cls) 36 { 37 Node* now=q[++op]; 38 for (int i=0;i<10;i++) 39 if (now->s[i] != NULL) 40 { 41 if (now->s[i] != root) 42 q[++cls]=now->s[i]; 43 if (now != root) 44 now->s[i]->fail=now->fail->s[i]; 45 else 46 now->s[i]->fail=root; 47 } 48 else 49 now->s[i]=now->fail->s[i]; 50 } 51 } 52 53 int ans[maxn][maxn],temp[maxn][maxn],wk[maxn][maxn],sum[maxn][maxn]; 54 55 int main() 56 { 57 root=&t[1]; 58 int n,m,mod; 59 scanf("%d%d%d",&n,&m,&mod); 60 scanf("%s",s); 61 insert(s); 62 build(); 63 ans[1][1]=1; 64 for (int i=1;i<=m;i++) 65 for (int j=0;j<10;j++) 66 { 67 int x=t[i].s[j]-t; 68 if (x < ne) 69 wk[i][x]++; 70 } 71 for (int i=1;i<=m;i++) 72 sum[i][i]=1; 73 while (n) 74 { 75 if (n&1) 76 { 77 memset(temp,0,sizeof(temp)); 78 for (int i=1;i<=m;i++) 79 for (int j=1;j<=m;j++) 80 for (int k=1;k<=m;k++) 81 (temp[i][j]+=sum[i][k]*wk[k][j])%=mod; 82 for (int i=1;i<=m;i++) 83 for (int j=1;j<=m;j++) 84 sum[i][j]=temp[i][j]; 85 } 86 memset(temp,0,sizeof(temp)); 87 n>>=1; 88 for (int i=1;i<=m;i++) 89 for (int j=1;j<=m;j++) 90 for (int k=1;k<=m;k++) 91 (temp[i][j]+=wk[i][k]*wk[k][j])%=mod; 92 for (int i=1;i<=m;i++) 93 for (int j=1;j<=m;j++) 94 wk[i][j]=temp[i][j]; 95 } 96 memset(temp,0,sizeof(temp)); 97 for (int i=1;i<=m;i++) 98 for (int j=1;j<=m;j++) 99 for (int k=1;k<=m;k++) 100 (temp[i][j]+=ans[i][k]*sum[k][j])%=mod; 101 int now=0; 102 for (int i=1;i<=m;i++) 103 (now+=temp[1][i])%=mod; 104 printf("%d\n",now); 105 return 0; 106 }
bzoj1010
斜率优化的DP
1 #include <cstdio> 2 3 #define maxn 50010 4 5 #ifdef unix 6 #define LL "%lld" 7 #else 8 #define LL "%I64d" 9 #endif 10 11 long long n,l; 12 long long sum[maxn],q[maxn],dp[maxn]; 13 14 inline long long sqr(long long x) 15 { 16 return x * x; 17 } 18 19 inline long long A(long long x) 20 { 21 return sum[x]+x; 22 } 23 24 inline long long B(long long x) 25 { 26 return sum[x]+x+l+1; 27 } 28 29 int main() 30 { 31 scanf(LL LL,&n,&l); 32 for (long long i=1;i<=n;i++) 33 { 34 long long x; 35 scanf(LL ,&x); 36 sum[i]=sum[i-1]+x; 37 } 38 long long op=0,cls=0; 39 for (long long i=1;i<=n;i++) 40 { 41 while (op < cls && dp[q[op+1]]-dp[q[op]]+sqr(B(q[op+1]))-sqr(B(q[op])) <= 2*A(i) * (B(q[op+1])-B(q[op]))) 42 op++; 43 dp[i]=dp[q[op]]+sqr(A(i)-B(q[op])); 44 while (op < cls) 45 { 46 if ((dp[q[cls]]-dp[q[cls-1]]+sqr(B(q[cls]))-sqr(B(q[cls-1]))) * (B(i)-B(q[cls])) > (dp[i]-dp[q[cls]]+sqr(B(i))-sqr(B(q[cls]))) * (B(q[cls])-B(q[cls-1]))) 47 cls--; 48 else 49 break; 50 } 51 q[++cls]=i; 52 } 53 printf(LL,dp[n]); 54 return 0; 55 }
bzoj1011
一直想不出来怎么优化,结果做法是。。。太过于遥远的行星可以理解为距离相同
1 #include <cstdio> 2 #include <cmath> 3 4 #define maxn 100010 5 #define t 60 6 #define eps 1e-8 7 8 double f[maxn],a; 9 int n,m[maxn]; 10 11 int main() 12 { 13 scanf("%d%lf",&n,&a); 14 for (int i=1;i<=n;i++) 15 scanf("%d",&m[i]); 16 for (int i=1;i<=t;i++) 17 { 18 int x=(int)(eps+floor(a*i)); 19 for (int j=1;j<=x;j++) 20 f[i]+=1.0*m[i]*m[j]/(i-j); 21 } 22 for (int i=t+1;i<=n;i++) 23 { 24 int l=(int)(eps+floor(a*(i-t))); 25 int x=(int)(eps+floor(a*i)); 26 for (int j=l+1;j<=x;j++) 27 f[i]+=1.0*m[i]*m[j]/(i-j); 28 f[i]+=1.0*m[i]*f[i-t]/m[i-t]*(i-t-1.0*l/2)/(i-1.0*l/2); 29 } 30 for (int i=1;i<=n;i++) 31 printf("%.6lf\n",f[i]); 32 return 0; 33 }
bzoj1012
可以用线段树,单调队列等一堆东西来写。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 int q[maxn],num[maxn]; 9 int cls=0; 10 int n,d; 11 12 int main() 13 { 14 char s[2]; 15 scanf("%d%d",&n,&d); 16 int ans=0,x,sum=0; 17 while (n--) 18 { 19 scanf("%s%d",s,&x); 20 if (s[0] == 'A') 21 { 22 (x+=ans)%=d; 23 q[++cls]=x; 24 num[cls]=++sum; 25 while (q[cls] > q[cls-1] && cls > 1) 26 { 27 q[cls-1]=q[cls]; 28 num[cls-1]=num[cls]; 29 cls--; 30 } 31 } 32 else 33 { 34 int now=lower_bound(num+1,num+cls+1,sum-x+1)-num; 35 printf("%d\n",q[now]); 36 ans=q[now]; 37 } 38 } 39 return 0; 40 }
bzoj1013
高斯消元模板题
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 15 8 #define eps 1e-6 9 10 int n; 11 double now[maxn],f[maxn][maxn],ans[maxn]; 12 13 inline void gauss() 14 { 15 for (int i=1;i<n;i++) 16 { 17 int _max=i; 18 for (int j=i+1;j<=n;j++) 19 if (fabs(f[j][i]) > fabs(f[_max][i])) 20 _max=i; 21 if (fabs(f[_max][i]) > eps) 22 { 23 for (int j=1;j<=n+1;j++) 24 swap(f[_max][j],f[i][j]); 25 for (int j=i+1;j<=n;j++) 26 if (fabs(f[j][i]) > eps) 27 { 28 double now=-f[j][i]/f[i][i]; 29 for (int k=i;k<=n+1;k++) 30 f[j][k]+=f[i][k]*now; 31 } 32 } 33 } 34 for (int i=n;i;i--) 35 { 36 double now=f[i][n+1]; 37 for (int j=i+1;j<=n;j++) 38 now-=ans[j]*f[i][j]; 39 ans[i]=now/f[i][i]; 40 } 41 for (int i=1;i<n;i++) 42 printf("%.3lf ",ans[i]); 43 printf("%.3lf\n",ans[n]); 44 } 45 46 int main() 47 { 48 scanf("%d",&n); 49 for (int i=1;i<=n;i++) 50 scanf("%lf",&now[i]); 51 for (int i=1;i<=n;i++) 52 for (int j=1;j<=n;j++) 53 { 54 double x; 55 scanf("%lf",&x); 56 f[i][j]=2*(now[j]-x); 57 f[i][n+1]+=now[j]*now[j]-x*x; 58 } 59 gauss(); 60 return 0; 61 }
bzoj1014
splay维护hash值
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 300010 5 6 const unsigned int mod=27; 7 8 unsigned int hash[maxn]; 9 10 struct Node 11 { 12 int c,size; 13 unsigned int v; 14 Node *s[2],*par; 15 Node() 16 { 17 c=size=0; 18 v=0; 19 } 20 }; 21 22 struct splay 23 { 24 Node t[maxn],null; 25 Node *root; 26 int ne; 27 28 splay() 29 { 30 null.s[0]=null.s[1]=null.par=&null; 31 t[0].s[0]=&null,t[0].s[1]=&t[1],t[0].par=&null,t[0].size=2,t[0].c=0,t[0].v=0; 32 t[1].s[0]=&null,t[1].s[1]=&null,t[1].par=&t[0],t[1].size=1,t[1].c=0,t[1].v=0; 33 root=&t[0]; 34 ne=2; 35 } 36 37 void travel(Node* now) 38 { 39 if (now->s[0] != &null) 40 travel(now->s[0]); 41 printf("%c",now->c+'a'-1); 42 if (now->s[1] != &null) 43 travel(now->s[1]); 44 } 45 46 inline void _update(Node* now) 47 { 48 now->size=now->s[0]->size+now->s[1]->size+1; 49 now->v=now->s[0]->v+now->c*hash[now->s[0]->size]+now->s[1]->v*hash[now->s[0]->size+1]; 50 } 51 52 inline void _rot(Node* now,int l) 53 { 54 int r=!l; 55 Node* s=now->s[l]; 56 Node* p=now->par; 57 (now->s[l]=s->s[r])->par=now; 58 (s->s[r]=now)->par=s; 59 s->par=p; 60 if (p != &null) 61 p->s[now == p->s[1]]=s; 62 _update(now); 63 _update(s); 64 } 65 66 inline void _splay(Node* now,Node* goal) 67 { 68 while (now->par != goal) 69 { 70 Node* p=now->par; 71 Node* g=p->par; 72 bool dp=now == p->s[1]; 73 bool dg=p == g->s[1]; 74 if (g == goal) 75 { 76 _rot(p,dp); 77 break; 78 } 79 if (dp == dg) 80 { 81 _rot(g,dg); 82 _rot(p,dp); 83 } 84 else 85 { 86 _rot(p,dp); 87 _rot(g,dg); 88 } 89 } 90 if (goal == &null) 91 root=now; 92 } 93 94 inline Node* _select(int v) 95 { 96 Node* now=root; 97 while (1) 98 { 99 if (now == &null) 100 return now; 101 if (now->s[0]->size+1 == v) 102 return now; 103 if (v <= now->s[0]->size) 104 now=now->s[0]; 105 else 106 { 107 v-=now->s[0]->size+1; 108 now=now->s[1]; 109 } 110 } 111 } 112 113 inline void change(int pos,char ch) 114 { 115 Node* p=_select(pos); 116 _splay(p,&null); 117 p->c=ch-'a'+1; 118 _update(p); 119 } 120 121 inline void insert(int pos,char ch) 122 { 123 Node* p=_select(pos); 124 Node* q=_select(pos+1); 125 _splay(p,&null); 126 _splay(q,root); 127 (q->s[0]=&t[ne++])->par=q; 128 Node* now=q->s[0]; 129 now->s[0]=now->s[1]=&null; 130 now->c=ch-'a'+1; 131 now->size=1; 132 now->v=ch-'a'+1; 133 _update(q); 134 _update(p); 135 } 136 137 inline bool check(int x,int y,int len) 138 { 139 Node* p=_select(x); 140 Node* q=_select(x+len+1); 141 _splay(p,&null); 142 _splay(q,root); 143 unsigned int ans=q->s[0]->v; 144 p=_select(y); 145 q=_select(y+len+1); 146 _splay(p,&null); 147 _splay(q,root); 148 return q->s[0]->v == ans; 149 } 150 151 inline int query(int x,int y) 152 { 153 int len=root->size; 154 if (x == y) 155 return len-x-1; 156 Node* p=_select(x+1); 157 Node* q=_select(y+1); 158 if (p->c != q->c) 159 return 0; 160 int l=1,r=len-y,ans=0; 161 while (l < r) 162 { 163 int mid=(l+r)>>1; 164 if (check(x,y,mid)) 165 { 166 ans=mid; 167 l=mid+1; 168 } 169 else 170 r=mid; 171 } 172 return ans; 173 } 174 }t; 175 176 int main() 177 { 178 //freopen("1.in","r",stdin); 179 //freopen("1.out","w",stdout); 180 int _,x,y; 181 char ch[2],s[2]; 182 char st[maxn]; 183 scanf("%s",st); 184 hash[0]=1; 185 for (int i=1;i<=maxn;i++) 186 hash[i]=hash[i-1] * mod; 187 int len=strlen(st); 188 for (int i=0;i<len;i++) 189 t.insert(i+1,st[i]); 190 scanf("%d",&_); 191 while (_--) 192 { 193 scanf("%s",ch); 194 if (ch[0] == 'Q') 195 { 196 scanf("%d%d",&x,&y); 197 if (x > y) 198 x^=y^=x^=y; 199 printf("%d\n",t.query(x,y)); 200 } 201 if (ch[0] == 'R') 202 { 203 scanf("%d%s",&x,s); 204 t.change(x+1,s[0]); 205 } 206 if (ch[0] == 'I') 207 { 208 scanf("%d%s",&x,s); 209 t.insert(x+1,s[0]); 210 } 211 } 212 return 0; 213 }
bzoj1015
倒着做并查集
1 #include <cstdio> 2 #include <bitset> 3 4 using namespace std; 5 6 #define maxn 2000010 7 #define maxm 200010 8 9 bitset <maxn> flag; 10 11 struct edge 12 { 13 int to; 14 edge *next; 15 }e[maxm<<1],*head[maxn]; 16 17 int n,m,ne=0; 18 int f[maxn],r[maxn]; 19 int des[maxn],ans[maxn]; 20 21 int find(int x) 22 { 23 if (f[x] == x) 24 return x; 25 return f[x]=find(f[x]); 26 } 27 28 int _union(int a,int b) 29 { 30 int x=find(a); 31 int y=find(b); 32 if (x == y) 33 return 0; 34 if (r[x] < r[y]) 35 { 36 f[x]=y; 37 r[y]+=r[x]; 38 } 39 else 40 { 41 f[y]=x; 42 r[x]+=r[y]; 43 } 44 return 1; 45 } 46 47 inline void add_edge(int from,int to) 48 { 49 e[ne].to=to; 50 e[ne].next=head[from]; 51 head[from]=&e[ne++]; 52 } 53 54 int main() 55 { 56 scanf("%d%d",&n,&m); 57 for (int i=1;i<=m;i++) 58 { 59 int x,y; 60 scanf("%d%d",&x,&y); 61 add_edge(x,y); 62 add_edge(y,x); 63 } 64 for (int i=0;i<n;i++) 65 flag[i]=1; 66 int k; 67 scanf("%d",&k); 68 for (int i=1;i<=k;i++) 69 { 70 scanf("%d",&des[i]); 71 flag[des[i]]=0; 72 } 73 int size=0; 74 for (int i=0;i<n;i++) 75 f[i]=i; 76 for (int i=0;i<n;i++) 77 if (flag[i]) 78 size++; 79 for (int i=0;i<n;i++) 80 if (flag[i]) 81 for (edge *p=head[i];p;p=p->next) 82 if (flag[p->to]) 83 size-=_union(i,p->to); 84 ans[k]=size; 85 for (int i=k;i;i--) 86 { 87 if (!flag[des[i]]) 88 size++; 89 flag[des[i]]=1; 90 for (edge *p=head[des[i]];p;p=p->next) 91 if (flag[p->to]) 92 size-=_union(des[i],p->to); 93 ans[i-1]=size; 94 } 95 for (int i=0;i<=k;i++) 96 printf("%d\n",ans[i]); 97 return 0; 98 }
bzoj1024
爆搜
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 20 7 8 double ans=1e+18; 9 10 inline double dfs(double x,double y,int rem) 11 { 12 if (x < y) 13 swap(x,y); 14 if (rem == 1) 15 return x/y; 16 double now=1e+18; 17 double r=1/(double)rem; 18 for (int i=1;i<rem;i++) 19 { 20 now=min(now,max(dfs(x*r*i,y,i),dfs(x-x*r*i,y,rem-i))); 21 now=min(now,max(dfs(x,y*r*i,i),dfs(x,y-y*r*i,rem-i))); 22 } 23 return now; 24 } 25 26 int main() 27 { 28 double x,y; 29 int n; 30 scanf("%lf%lf%d",&x,&y,&n); 31 printf("%.6lf\n",dfs(x,y,n)); 32 return 0; 33 }
bzoj1026
水水的数位DP
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 15 7 8 int bit[maxn]; 9 int f[maxn][10]; 10 11 inline int calc(int n) 12 { 13 if (!n) 14 return 0; 15 int ans=0,len=10; 16 while (bit[len] > n) 17 len--; 18 for (int i=1;i<len;i++) 19 for (int j=1;j<=9;j++) 20 ans+=f[i][j]; 21 int rest=n/bit[len]; 22 for (int i=1;i<rest;i++) 23 ans+=f[len][i]; 24 int pre=rest; 25 n%=bit[len]; 26 for (int i=len-1;i;i--) 27 { 28 rest=n/bit[i]; 29 if (i != 1) 30 { 31 for (int j=0;j<rest;j++) 32 if (abs(pre-j) >= 2) 33 ans+=f[i][j]; 34 } 35 else 36 { 37 for (int j=0;j<=rest;j++) 38 if (abs(pre-j) >= 2) 39 ans+=f[i][j]; 40 } 41 if (abs(rest-pre) < 2) 42 break; 43 pre=rest; 44 n%=bit[i]; 45 } 46 return ans; 47 } 48 49 int main() 50 { 51 bit[1]=1; 52 for (int i=2;i<=10;i++) 53 bit[i]=bit[i-1]*10; 54 for (int i=0;i<=9;i++) 55 f[1][i]=1; 56 for (int i=2;i<=10;i++) 57 for (int j=0;j<=9;j++) 58 for (int k=0;k<=9;k++) 59 if (abs(j-k) >= 2) 60 f[i][j]+=f[i-1][k]; 61 int a,b; 62 scanf("%d%d",&a,&b); 63 printf("%d\n",calc(b)-calc(a-1)); 64 return 0; 65 }
bzoj1029
开个堆乱搞即可
#include <cstdio> #include <algorithm> #include <queue> using namespace std; #define maxn 1000010 pair <int,int> a[maxn]; inline void read(int &x) { char ch; while (ch=getchar(),ch > '9' || ch < '0'); x=ch-'0'; while (ch=getchar(),ch <= '9' && ch >= '0') x=(x<<3)+x+x+ch-'0'; } priority_queue <int> q; int main() { int n; read(n); for (int i=1;i<=n;i++) { read(a[i].second); read(a[i].first); } sort(a+1,a+n+1); int now=0,ans=0; for (int i=1;i<=n;i++) if (now+a[i].second <= a[i].first) { now+=a[i].second; ans++; q.push(a[i].second); } else if (q.top() > a[i].second) { now-=q.top()-a[i].second; q.pop(); q.push(a[i].second); } printf("%d\n",ans); return 0; }
bzoj1030
AC自动机+DP
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxl 110 5 #define maxn 6010 6 #define mod 10007 7 8 struct Node 9 { 10 bool end; 11 Node *s[26],*fail; 12 13 inline Node() 14 { 15 end=0; 16 fail=NULL; 17 for (int i=0;i<26;i++) 18 s[i]=NULL; 19 } 20 }t[maxn],*root,*q[maxn]; 21 22 int ne=0; 23 char s[maxl]; 24 25 inline void init() 26 { 27 root=&t[0]; 28 root->fail=root; 29 ne=1; 30 } 31 32 inline void insert(char* s) 33 { 34 Node* now=root; 35 int l=strlen(s); 36 for (int i=0;i<l;i++) 37 { 38 int p=s[i]-'A'; 39 if (now->s[p] == NULL) 40 now->s[p]=&t[ne++]; 41 now=now->s[p]; 42 } 43 now->end=1; 44 } 45 46 inline void build() 47 { 48 int op=0,cls=1; 49 q[1]=root; 50 for (int i=0;i<26;i++) 51 if (root->s[i] == NULL) 52 root->s[i]=root; 53 while (op != cls) 54 { 55 Node* now=q[++op]; 56 for (int i=0;i<26;i++) 57 if (now->s[i] != NULL) 58 { 59 if (now->s[i] != root) 60 q[++cls]=now->s[i]; 61 if (now != root) 62 { 63 now->s[i]->fail=now->fail->s[i]; 64 now->s[i]->end|=now->s[i]->fail->end; 65 } 66 else 67 now->s[i]->fail=root; 68 } 69 else 70 now->s[i]=now->fail->s[i]; 71 } 72 } 73 74 int f[maxl][maxn][2]; 75 76 int main() 77 { 78 int n,m; 79 scanf("%d%d",&n,&m); 80 init(); 81 for (int i=1;i<=n;i++) 82 { 83 scanf("%s",s); 84 insert(s); 85 } 86 build(); 87 f[0][0][0]=1; 88 for (int i=0;i<m;i++) 89 for (int j=0;j<ne;j++) 90 for (int k=0;k<2;k++) 91 { 92 Node* now=&t[j]; 93 for (int l=0;l<26;l++) 94 (f[i+1][now->s[l]-t][k|now->s[l]->end]+=f[i][j][k])%=mod; 95 } 96 int ans=0; 97 for (int i=0;i<ne;i++) 98 (ans+=f[m][i][1])%=mod; 99 printf("%d\n",ans); 100 return 0; 101 }
bzoj1031
不用height的后缀数组。。。
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 200010 5 6 char ch[maxn]; 7 int a[maxn]; 8 int sa[maxn]; 9 10 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 11 12 inline int cmp(int *r,int a,int b,int l) 13 {return r[a]==r[b]&&r[a+l]==r[b+l];} 14 15 inline void da(int *r,int *sa,int n,int m) 16 { 17 int i,j,p,*x=wa,*y=wb,*t; 18 for(i=0;i<m;i++) ws[i]=0; 19 for(i=0;i<n;i++) ws[x[i]=r[i]]++; 20 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 21 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 22 for(j=1,p=1;p<n;j*=2,m=p) 23 { 24 for(p=0,i=n-j;i<n;i++) y[p++]=i; 25 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 26 for(i=0;i<n;i++) wv[i]=x[y[i]]; 27 for(i=0;i<m;i++) ws[i]=0; 28 for(i=0;i<n;i++) ws[wv[i]]++; 29 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 30 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; 31 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 32 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 33 } 34 return; 35 } 36 37 int rank[maxn],height[maxn]; 38 39 inline void calheight(int *r,int *sa,int n) 40 { 41 int i,j,k=0; 42 for(i=1;i<=n;i++) rank[sa[i]]=i; 43 for(i=0;i<n;height[rank[i++]]=k) 44 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 45 return; 46 } 47 48 int main() 49 { 50 scanf("%s",ch); 51 int len=strlen(ch); 52 for (int i=0;i<len;i++) 53 { 54 a[i]=a[i+len]=ch[i]; 55 ch[i+len]=ch[i]; 56 } 57 len<<=1; 58 da(a,sa,len+1,200); 59 len>>=1; 60 for (int i=1;i<=len<<1;i++) 61 if (sa[i] < len) 62 printf("%c",ch[sa[i]+len-1]); 63 return 0; 64 }
bzoj1034
排序,然后两边往中间扫即可,想想田忌是怎么赢的,思想是贪心
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 int a[maxn],b[maxn]; 9 10 inline void read(int &x) 11 { 12 char ch; 13 while (ch=getchar(),ch > '9' || ch < '0'); 14 x=ch-'0'; 15 while (ch=getchar(),ch <= '9' && ch >= '0') 16 x=(x<<3)+x+x+ch-'0'; 17 } 18 19 int main() 20 { 21 int n; 22 read(n); 23 for (int i=1;i<=n;i++) 24 read(a[i]); 25 for (int i=1;i<=n;i++) 26 read(b[i]); 27 sort(a+1,a+n+1); 28 sort(b+1,b+n+1); 29 int al=1,ar=n,bl=1,br=n,ans=0; 30 while (al <= ar && bl <= br) 31 { 32 if (a[al] > b[bl]) 33 { 34 ans+=2; 35 al++; 36 bl++; 37 } 38 else 39 { 40 if (a[ar] > b[br]) 41 { 42 ans+=2; 43 ar--; 44 br--; 45 } 46 else 47 { 48 ans+=a[al] == b[br]; 49 al++; 50 br--; 51 } 52 } 53 } 54 printf("%d ",ans); 55 al=bl=1,ar=br=n,ans=0; 56 while (al <= ar && bl <= br) 57 { 58 if (b[bl] > a[al]) 59 { 60 ans+=2; 61 al++; 62 bl++; 63 } 64 else 65 { 66 if (b[br] > a[ar]) 67 { 68 ans+=2; 69 ar--; 70 br--; 71 } 72 else 73 { 74 ans+=a[ar] == b[bl]; 75 bl++; 76 ar--; 77 } 78 } 79 } 80 printf("%d\n",2*n-ans); 81 return 0; 82 }
bzoj1036
lct模板题,注意null结点的初始值
1 #include <cstdio> 2 3 #define maxn 30010 4 #define inf 0x3f3f3f3f 5 6 struct Node 7 { 8 int v,max,sum; 9 bool rt; 10 Node* s[2],*par; 11 }t[maxn],null; 12 13 struct edge 14 { 15 int to; 16 edge *next; 17 }e[maxn<<1],*head[maxn]; 18 19 int ne=0; 20 int q[maxn]; 21 bool vis[maxn]; 22 23 inline void add_edge(int from,int to) 24 { 25 e[ne].to=to; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void bfs() 31 { 32 int op=0,cls=1; 33 q[1]=1; 34 vis[1]=1; 35 while (op != cls) 36 { 37 int x=q[++op]; 38 for (edge *p=head[x];p;p=p->next) 39 if (!vis[p->to]) 40 { 41 q[++cls]=p->to; 42 vis[p->to]=1; 43 t[p->to].par=&t[x]; 44 } 45 } 46 } 47 48 inline int max(int a,int b) 49 { 50 return a > b ? a : b; 51 } 52 53 inline void _update(Node* now) 54 { 55 now->sum=now->s[0]->sum+now->s[1]->sum+now->v; 56 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v); 57 } 58 59 inline void _rot(Node* now,int l) 60 { 61 int r=!l; 62 Node* p=now->par; 63 Node* s=now->s[l]; 64 (now->s[l]=s->s[r])->par=now; 65 (s->s[r]=now)->par=s; 66 s->par=p; 67 if (!now->rt) 68 p->s[now == p->s[1]]=s; 69 else 70 { 71 now->rt=0; 72 s->rt=1; 73 } 74 _update(now); 75 _update(s); 76 } 77 78 inline void _splay(Node* now) 79 { 80 while (!now->rt) 81 { 82 Node* p=now->par; 83 Node* g=p->par; 84 bool dp=now == p->s[1]; 85 bool dg=p == g->s[1]; 86 if (p->rt) 87 { 88 _rot(p,dp); 89 return; 90 } 91 if (dp == dg) 92 { 93 _rot(g,dg); 94 _rot(p,dp); 95 } 96 else 97 { 98 _rot(p,dp); 99 _rot(g,dg); 100 } 101 } 102 } 103 104 inline void access(Node* now) 105 { 106 Node* p=now; 107 Node* q=&null; 108 do 109 { 110 _splay(p); 111 if (p->s[1] != &null) 112 p->s[1]->rt=1; 113 p->s[1]=q; 114 if (q != &null) 115 { 116 q->par=p; 117 q->rt=0; 118 } 119 _update(p); 120 q=p; 121 p=p->par; 122 } 123 while (p != &null); 124 } 125 126 inline Node* doit(Node* now) 127 { 128 Node* p; 129 _splay(now); 130 if (now->s[0] != &null) 131 { 132 for (p=now->s[0];p->s[1] != &null;p=p->s[1]); 133 _splay(p); 134 } 135 return now; 136 } 137 138 inline int qsum(Node* u,Node* v) 139 { 140 access(u); 141 _splay(v); 142 if (v->par == &null) 143 return doit(v)->sum; 144 access(v); 145 _splay(u); 146 if (u->par == &null) 147 return doit(u)->sum; 148 return u->sum+doit(u->par)->sum; 149 } 150 151 inline int qmax(Node* u,Node* v) 152 { 153 access(u); 154 _splay(v); 155 if (v->par == &null) 156 return doit(v)->max; 157 access(v); 158 _splay(u); 159 if (u->par == &null) 160 return doit(u)->max; 161 return max(u->max,doit(u->par)->max); 162 } 163 164 inline void change(Node* now,int v) 165 { 166 _splay(now); 167 now->v=v; 168 _update(now); 169 } 170 171 int main() 172 { 173 null.s[0]=null.s[1]=null.par=&null; 174 null.max=-inf;null.sum=null.v=0; 175 null.rt=1; 176 int n; 177 scanf("%d",&n); 178 for (int i=1;i<n;i++) 179 { 180 int x,y; 181 scanf("%d%d",&x,&y); 182 add_edge(x,y); 183 add_edge(y,x); 184 } 185 for (int i=1;i<=n;i++) 186 { 187 scanf("%d",&t[i].v); 188 t[i].s[0]=t[i].s[1]=t[1].par=&null; 189 t[i].rt=1; 190 t[i].max=t[i].sum=t[i].v; 191 } 192 bfs(); 193 int _; 194 char s[10]; 195 scanf("%d",&_); 196 while (_--) 197 { 198 int x,y; 199 scanf("%s%d%d",s,&x,&y); 200 if (s[0] == 'C') 201 change(&t[x],y); 202 else 203 { 204 if (s[1] == 'M') 205 printf("%d\n",qmax(&t[x],&t[y])); 206 else 207 printf("%d\n",qsum(&t[x],&t[y])); 208 } 209 } 210 return 0; 211 }
bzoj1042
背包+容斥
1 #include <cstdio> 2 3 #define maxn 100010 4 5 int bit[10]; 6 int c[4],d[4]; 7 long long f[maxn]; 8 9 inline void pre() 10 { 11 f[0]=1; 12 for (int i=0;i<4;i++) 13 for (int j=c[i];j<maxn;j++) 14 f[j]+=f[j-c[i]]; 15 } 16 17 inline long long calc(int v) 18 { 19 long long ans=f[v]; 20 for (int i=1;i<=15;i++) 21 { 22 int sum=0,nowv=v; 23 for (int j=0;j<4;j++) 24 if (i&bit[j]) 25 { 26 nowv-=(d[j]+1)*c[j]; 27 sum++; 28 } 29 if (nowv < 0) 30 continue; 31 if (sum&1) 32 ans-=f[nowv]; 33 else 34 ans+=f[nowv]; 35 } 36 return ans; 37 } 38 39 int main() 40 { 41 bit[0]=1; 42 for (int i=1;i<=5;i++) 43 bit[i]=bit[i-1]+bit[i-1]; 44 int _; 45 for (int i=0;i<4;i++) 46 scanf("%d",&c[i]); 47 pre(); 48 scanf("%d",&_); 49 while (_--) 50 { 51 int v; 52 for (int i=0;i<4;i++) 53 scanf("%d",&d[i]); 54 scanf("%d",&v); 55 printf("%lld\n",calc(v)); 56 } 57 return 0; 58 }
bzoj1045
排序后往中位数方向传递(大概就是这个意思吧。。。)可以直接算答案
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1000010 7 8 #ifdef unix 9 #define LL "%lld" 10 #else 11 #define LL "%I64d" 12 #endif 13 14 inline void read(long long &x) 15 { 16 char ch; 17 while (ch=getchar(),ch > '9' || ch < '0'); 18 x=ch-'0'; 19 while (ch=getchar(),ch <= '9' && ch >= '0') 20 x=(x<<3)+x+x+ch-'0'; 21 } 22 23 long long d[maxn]; 24 25 int main() 26 { 27 long long n,sum=0; 28 read(n); 29 for (long long i=1;i<=n;i++) 30 { 31 read(d[i]); 32 sum+=d[i]; 33 } 34 sum/=n; 35 for (long long i=1;i<=n;i++) 36 d[i]=d[i-1]+d[i]-sum; 37 sort(d+1,d+n+1); 38 long long ans=0,now=d[(n+1)>>1]; 39 for (long long i=1;i<=n;i++) 40 ans+=abs(d[i]-now); 41 printf(LL,ans); 42 return 0; 43 }
bzoj1046
nlogn的最长上升序列,后面的询问可以直接用f数组来搞
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 10010 7 8 int n,m,size; 9 int t[maxn<<2]; 10 int a[maxn],b[maxn],f[maxn]; 11 int ans[maxn]; 12 13 inline void _update(int rt) 14 { 15 t[rt]=max(t[rt<<1],t[rt<<1|1]); 16 } 17 18 void insert(int l,int r,int rt,int pos,int val) 19 { 20 if (l == r) 21 { 22 t[rt]=max(t[rt],val); 23 return; 24 } 25 int mid=(l+r)>>1; 26 if (pos <= mid) 27 insert(l,mid,rt<<1,pos,val); 28 else 29 insert(mid+1,r,rt<<1|1,pos,val); 30 _update(rt); 31 } 32 33 int query(int l,int r,int rt,int L,int R) 34 { 35 if (l >= L && r <= R) 36 return t[rt]; 37 int mid=(l+r)>>1,ans=0; 38 if (L <= mid) 39 ans=max(ans,query(l,mid,rt<<1,L,R)); 40 if (R > mid) 41 ans=max(ans,query(mid+1,r,rt<<1|1,L,R)); 42 return ans; 43 } 44 45 int main() 46 { 47 scanf("%d",&n); 48 for (int i=1;i<=n;i++) 49 { 50 scanf("%d",&a[i]); 51 b[i]=a[i]; 52 } 53 sort(b+1,b+n+1); 54 size=unique(b+1,b+n+1)-b-1; 55 for (int i=1;i<=n;i++) 56 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 57 f[n]=1; 58 insert(1,size,1,a[n],1); 59 int _max=0; 60 for (int i=n-1;i;i--) 61 { 62 f[i]=query(1,size,1,a[i]+1,size)+1; 63 _max=max(f[i],_max); 64 insert(1,size,1,a[i],f[i]); 65 } 66 scanf("%d",&m); 67 while (m--) 68 { 69 int x; 70 scanf("%d",&x); 71 if (x > _max) 72 { 73 puts("Impossible"); 74 continue; 75 } 76 int now=0,sum=x,prev=0,cnt=0; 77 for (int i=1;i<=n;i++) 78 if (f[i] >= x) 79 { 80 now=i; 81 prev=a[i]; 82 ans[++cnt]=b[a[i]]; 83 sum--; 84 break; 85 } 86 for (int i=now+1;i<=n;i++) 87 { 88 if (f[i] >= sum && a[i] > prev) 89 { 90 sum--; 91 prev=a[i]; 92 ans[++cnt]=b[a[i]]; 93 } 94 if (!sum) 95 break; 96 } 97 for (int i=1;i<x;i++) 98 printf("%d ",ans[i]); 99 printf("%d\n",ans[x]); 100 } 101 return 0; 102 }
bzoj1047
单调队列,经典的滑窗问题
1 #include <cstdio> 2 #include <queue> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1010 8 #define inf 0x3f3f3f3f 9 10 deque <pair<int,int> > q; 11 12 int num[maxn][maxn],_max[maxn][maxn],_min[maxn][maxn]; 13 int ans_max[maxn][maxn],ans_min[maxn][maxn]; 14 15 inline void read(int &x) 16 { 17 char ch; 18 while (ch=getchar(),ch > '9' || ch < '0'); 19 x=ch-'0'; 20 while (ch=getchar(),ch <= '9' && ch >= '0') 21 x=(x<<3)+x+x+ch-'0'; 22 } 23 24 int main() 25 { 26 int a,b,n; 27 read(a); 28 read(b); 29 read(n); 30 for (int i=1;i<=a;i++) 31 for (int j=1;j<=b;j++) 32 read(num[i][j]); 33 for (int i=1;i<=a;i++) 34 { 35 while (!q.empty()) 36 q.pop_front(); 37 for (int j=1;j<=n;j++) 38 { 39 while (!q.empty() && q.back().first < num[i][j]) 40 q.pop_back(); 41 q.push_back(make_pair(num[i][j],j)); 42 } 43 _max[i][n]=q.front().first; 44 for (int j=n+1;j<=b;j++) 45 { 46 if (q.front().second < j-n+1) 47 q.pop_front(); 48 while (!q.empty() && q.back().first < num[i][j]) 49 q.pop_back(); 50 q.push_back(make_pair(num[i][j],j)); 51 _max[i][j]=q.front().first; 52 } 53 } 54 for (int i=1;i<=a;i++) 55 { 56 while (!q.empty()) 57 q.pop_front(); 58 for (int j=1;j<=n;j++) 59 { 60 while (!q.empty() && q.back().first > num[i][j]) 61 q.pop_back(); 62 q.push_back(make_pair(num[i][j],j)); 63 } 64 _min[i][n]=q.front().first; 65 for (int j=n+1;j<=b;j++) 66 { 67 if (q.front().second < j-n+1) 68 q.pop_front(); 69 while (!q.empty() && q.back().first > num[i][j]) 70 q.pop_back(); 71 q.push_back(make_pair(num[i][j],j)); 72 _min[i][j]=q.front().first; 73 } 74 } 75 for (int i=n;i<=b;i++) 76 { 77 while (!q.empty()) 78 q.pop_front(); 79 for (int j=1;j<=n;j++) 80 { 81 while (!q.empty() && q.back().first < _max[j][i]) 82 q.pop_back(); 83 q.push_back(make_pair(_max[j][i],j)); 84 } 85 ans_max[n][i]=q.front().first; 86 for (int j=n+1;j<=a;j++) 87 { 88 if (q.front().second < j-n+1) 89 q.pop_front(); 90 while (!q.empty() && q.back().first < _max[j][i]) 91 q.pop_back(); 92 q.push_back(make_pair(_max[j][i],j)); 93 ans_max[j][i]=q.front().first; 94 } 95 } 96 for (int i=n;i<=b;i++) 97 { 98 while (!q.empty()) 99 q.pop_front(); 100 for (int j=1;j<=n;j++) 101 { 102 while (!q.empty() && q.back().first > _min[j][i]) 103 q.pop_back(); 104 q.push_back(make_pair(_min[j][i],j)); 105 } 106 ans_min[n][i]=q.front().first; 107 for (int j=n+1;j<=a;j++) 108 { 109 if (q.front().second < j-n+1) 110 q.pop_front(); 111 while (!q.empty() && q.back().first > _min[j][i]) 112 q.pop_back(); 113 q.push_back(make_pair(_min[j][i],j)); 114 ans_min[j][i]=q.front().first; 115 } 116 } 117 int ans=inf; 118 for (int i=n;i<=a;i++) 119 for (int j=n;j<=b;j++) 120 if (ans_max[i][j]-ans_min[i][j] < ans) 121 ans=ans_max[i][j]-ans_min[i][j]; 122 printf("%d\n",ans); 123 return 0; 124 }
bzoj1051
tarjan缩点之后统计出度为0的点的个数
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 20010 7 #define maxm 50010 8 9 struct edge 10 { 11 int to; 12 edge *next; 13 }e[maxm],*head[maxn]; 14 15 int ne=0,time=0,top=0,cnt; 16 int dfn[maxn],sta[maxn],low[maxn],belong[maxn],size[maxn]; 17 int in[maxn],out[maxn]; 18 bool vis[maxn]; 19 20 inline void add_edge(int from,int to) 21 { 22 e[ne].to=to; 23 e[ne].next=head[from]; 24 head[from]=&e[ne++]; 25 } 26 27 void tarjan(int now) 28 { 29 dfn[now]=low[now]=++time; 30 sta[++top]=now; 31 vis[now]=1; 32 for (edge *p=head[now];p;p=p->next) 33 if (!dfn[p->to]) 34 { 35 tarjan(p->to); 36 low[now]=min(low[now],low[p->to]); 37 } 38 else 39 if (vis[p->to]) 40 low[now]=min(low[now],dfn[p->to]); 41 if (dfn[now] == low[now]) 42 { 43 int v; 44 cnt++; 45 do 46 { 47 v=sta[top--]; 48 vis[v]=0; 49 belong[v]=cnt; 50 size[cnt]++; 51 } 52 while (v != now); 53 } 54 } 55 56 int main() 57 { 58 int n,m; 59 scanf("%d%d",&n,&m); 60 for (int i=1;i<=m;i++) 61 { 62 int x,y; 63 scanf("%d%d",&x,&y); 64 add_edge(x,y); 65 } 66 cnt=n; 67 for (int i=1;i<=n;i++) 68 if (!dfn[i]) 69 tarjan(i); 70 for (int i=1;i<=n;i++) 71 for (edge *p=head[i];p;p=p->next) 72 if (belong[i] != belong[p->to]) 73 { 74 in[belong[p->to]]++; 75 out[belong[i]]++; 76 add_edge(belong[i],belong[p->to]); 77 } 78 int now=0; 79 for (int i=n+1;i<=cnt;i++) 80 if (!out[i]) 81 now++; 82 if (now >= 2) 83 { 84 puts("0"); 85 return 0; 86 } 87 for (int i=n+1;i<=cnt;i++) 88 if (!out[i]) 89 { 90 printf("%d\n",size[i]); 91 return 0; 92 } 93 return 0; 94 }
bzoj1052
遮四个角落一定最优,二分边长,然后递归两层枚举遮哪一个角落,第三层check
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 20010 8 #define inf 0x3f3f3f3f 9 10 int n; 11 int x[maxn],y[maxn],mx[2]={inf,-inf},my[2]={inf,-inf}; 12 bool flag[maxn]; 13 14 inline bool check(int r) 15 { 16 for (int i=0;i<2;i++) 17 for (int j=0;j<2;j++) 18 { 19 memset(flag,1,sizeof(flag)); 20 int now=0,nowx=mx[i],nowy=my[j],nowmx[2]={inf,-inf},nowmy[2]={inf,-inf}; 21 for (int k=1;k<=n;k++) 22 if (abs(x[k]-nowx) <= r && abs(y[k]-nowy) <= r) 23 { 24 flag[k]=0; 25 now++; 26 if (now == n) 27 return 1; 28 } 29 else 30 { 31 nowmx[0]=min(nowmx[0],x[k]); 32 nowmy[0]=min(nowmy[0],y[k]); 33 nowmx[1]=max(nowmx[1],x[k]); 34 nowmy[1]=max(nowmy[1],y[k]); 35 } 36 for (int k=0;k<2;k++) 37 for (int l=0;l<2;l++) 38 { 39 int sum=now; 40 nowx=nowmx[k]; 41 nowy=nowmy[l]; 42 int max_x=-inf,max_y=-inf,min_x=inf,min_y=inf; 43 for (int m=1;m<=n;m++) 44 if (flag[m]) 45 { 46 if (abs(x[m]-nowx) <= r && abs(y[m]-nowy) <= r) 47 { 48 sum++; 49 if (sum == n) 50 return 1; 51 } 52 else 53 { 54 max_x=max(max_x,x[m]); 55 max_y=max(max_y,y[m]); 56 min_x=min(min_x,x[m]); 57 min_y=min(min_y,y[m]); 58 } 59 } 60 if (max_x-min_x <= r && max_y-min_y <= r) 61 return 1; 62 } 63 } 64 return 0; 65 } 66 67 inline void read(int &x) 68 { 69 char ch; 70 bool flag=0; 71 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-')); 72 if (ch == '-') 73 flag=1; 74 else 75 x=ch-'0'; 76 while (ch=getchar(),ch <= '9' && ch >= '0') 77 x=(x<<3)+x+x+ch-'0'; 78 if (flag) 79 x=-x; 80 } 81 82 int main() 83 { 84 read(n); 85 for (int i=1;i<=n;i++) 86 { 87 read(x[i]); 88 read(y[i]); 89 mx[1]=max(mx[1],x[i]); 90 my[1]=max(my[1],y[i]); 91 mx[0]=min(mx[0],x[i]); 92 my[0]=min(my[0],y[i]); 93 } 94 int l=0,r=inf,ans=0; 95 while (l < r) 96 { 97 int mid=(l+r)>>1; 98 if (check(mid)) 99 ans=r=mid; 100 else 101 l=mid+1; 102 } 103 printf("%d\n",ans); 104 return 0; 105 }
bzoj1058
正解我不会。。。写了两颗SBT来暴力,加了些优化还是能12s的
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1500010 7 #define inf 0x3f3f3f3f 8 9 struct Node 10 { 11 int v,size; 12 Node *s[2]; 13 14 Node() 15 { 16 size=1; 17 } 18 }; 19 20 struct sbt 21 { 22 Node t[maxn],null; 23 Node *root; 24 int ne; 25 26 inline sbt() 27 { 28 null.s[0]=null.s[1]=&null; 29 null.size=0; 30 root=&null; 31 ne=0; 32 } 33 34 inline void _update(Node* now) 35 { 36 now->size=now->s[0]->size+now->s[1]->size+1; 37 } 38 39 inline Node* new_Node() 40 { 41 Node* now=&t[ne++]; 42 now->s[0]=now->s[1]=&null; 43 return now; 44 } 45 46 inline void _rot(Node* &now,int l) 47 { 48 int r=!l; 49 Node* s=now->s[l]; 50 now->s[l]=s->s[r]; 51 s->s[r]=now; 52 _update(now); 53 _update(s); 54 now=s; 55 } 56 57 void _maintain(Node* &now,int l) 58 { 59 int r=!l; 60 if (now->s[l]->s[l]->size > now->s[r]->size) 61 _rot(now,l); 62 else 63 if (now->s[l]->s[r]->size > now->s[r]->size) 64 { 65 _rot(now->s[l],r); 66 _rot(now,l); 67 } 68 else 69 return; 70 _maintain(now->s[0],0); 71 _maintain(now->s[1],1); 72 _maintain(now,0); 73 _maintain(now,1); 74 } 75 76 void insert(Node* &now,int v) 77 { 78 if (now == &null) 79 { 80 now=new_Node(); 81 now->v=v; 82 return; 83 } 84 now->size++; 85 insert(now->s[v >= now->v],v); 86 _maintain(now,v >= now->v); 87 } 88 89 int del(Node* &now,int v) 90 { 91 now->size--; 92 if ((now->v == v) || (v < now->v && now->s[0] == &null) || (v > now->v && now->s[1] == &null)) 93 { 94 int t=now->v; 95 if (now->s[0] == &null) 96 now=now->s[1]; 97 else 98 if (now->s[1] == &null) 99 now=now->s[0]; 100 else 101 now->v=del(now->s[1],0); 102 return t; 103 } 104 else 105 del(now->s[v > now->v],v); 106 } 107 108 inline Node* _select(int v) 109 { 110 Node* now=root; 111 while (v) 112 { 113 if (now->s[0]->size+1 == v) 114 return now; 115 if (v <= now->s[0]->size) 116 now=now->s[0]; 117 else 118 { 119 v-=now->s[0]->size+1; 120 now=now->s[1]; 121 } 122 } 123 } 124 125 inline int pred(int v) 126 { 127 Node* now=root; 128 int ans=-inf; 129 while (1) 130 { 131 if (now == &null) 132 return ans; 133 if (now->v <= v) 134 { 135 ans=now->v; 136 now=now->s[1]; 137 } 138 else 139 now=now->s[0]; 140 } 141 return ans; 142 } 143 144 inline int succ(int v) 145 { 146 Node* now=root; 147 int ans=inf; 148 while (1) 149 { 150 if (now == &null) 151 return ans; 152 if (now->v >= v) 153 { 154 ans=now->v; 155 now=now->s[0]; 156 } 157 else 158 now=now->s[1]; 159 } 160 return ans; 161 } 162 163 inline int get_min() 164 { 165 int ans=inf; 166 Node* now=root; 167 while (1) 168 { 169 if (now == &null) 170 return ans; 171 ans=now->v; 172 now=now->s[0]; 173 } 174 } 175 176 void travel(Node* now) 177 { 178 if (now->s[0] != &null) 179 travel(now->s[0]); 180 printf("%d ",now->v); 181 if (now->s[1] != &null) 182 travel(now->s[1]); 183 } 184 }t1,t2; 185 186 struct xxx 187 { 188 int begin,end; 189 }a[maxn]; 190 191 int main() 192 { 193 //freopen("form.in","r",stdin); 194 //freopen("form.out","w",stdout); 195 int n,_; 196 scanf("%d%d",&n,&_); 197 int now_min=inf,crf_min=inf; 198 for (int i=1;i<=n;i++) 199 { 200 scanf("%d",&a[i].begin); 201 a[i].end=a[i].begin; 202 now_min=min(now_min,abs(a[i].begin-t1.pred(a[i].begin))); 203 now_min=min(now_min,abs(t1.succ(a[i].begin)-a[i].begin)); 204 t1.insert(t1.root,a[i].begin); 205 if (i != 1) 206 t2.insert(t2.root,abs(a[i].begin-a[i-1].end)); 207 } 208 crf_min=t2.get_min(); 209 while (_--) 210 { 211 char s[20]; 212 int x,y; 213 scanf("%s",s); 214 if (s[0] == 'I') 215 { 216 scanf("%d%d",&x,&y); 217 if (x != n) 218 { 219 t2.del(t2.root,abs(a[x].end-a[x+1].begin)); 220 t2.insert(t2.root,abs(y-a[x+1].begin)); 221 } 222 t2.insert(t2.root,abs(y-a[x].end)); 223 crf_min=t2.get_min(); 224 a[x].end=y; 225 if (now_min) 226 { 227 now_min=min(now_min,abs(y-t1.pred(y))); 228 now_min=min(now_min,abs(t1.succ(y)-y)); 229 t1.insert(t1.root,y); 230 } 231 } 232 if (s[0] == 'M' && s[4] == 'G') 233 printf("%d\n",crf_min); 234 if (s[0] == 'M' && s[4] == 'S') 235 printf("%d\n",now_min); 236 } 237 return 0; 238 }
bzoj1059
二分图匹配,行匹配列
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 410 8 #define maxm 40010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm<<1],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 int op=0,cls=1; 41 memset(d,-1,sizeof(d)); 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 q[++cls]=p->to; 51 d[p->to]=d[x]+1; 52 } 53 } 54 return d[t] != -1; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int main() 84 { 85 int _; 86 scanf("%d",&_); 87 while (_--) 88 { 89 memset(head,0x0,sizeof(head)); 90 ne=0; 91 int n; 92 scanf("%d",&n); 93 for (int i=1;i<=n;i++) 94 for (int j=1;j<=n;j++) 95 { 96 int x; 97 scanf("%d",&x); 98 if (x) 99 add_edge(i,j+n,1); 100 } 101 for (int i=1;i<=n;i++) 102 { 103 add_edge(s,i,1); 104 add_edge(i+n,t,1); 105 } 106 int ans=dinic(); 107 if (ans == n) 108 puts("Yes"); 109 else 110 puts("No"); 111 } 112 return 0; 113 }
bzoj1061
神一般的费用流转化,具体参见byvoid神犇的博客。。。后来会了单纯形也没重新来写这道题,就贴费用流代码吧
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #include <bitset> 6 7 using namespace std; 8 9 #define maxn 1010 10 #define maxm 1000010 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow,cost; 16 edge *part,*next; 17 }e[maxm<<1],*head[maxn],*prev[maxn]; 18 19 int ne=0; 20 int s=0,t=maxn-1; 21 int d[maxn],q[maxn]; 22 bitset <maxn> flag; 23 24 inline void add(int from,int to,int flow,int cost) 25 { 26 e[ne].to=to; 27 e[ne].flow=flow; 28 e[ne].cost=cost; 29 e[ne].next=head[from]; 30 head[from]=&e[ne++]; 31 } 32 33 inline void add_edge(int from,int to,int flow,int cost) 34 { 35 e[ne].part=&e[ne+1]; 36 e[ne+1].part=&e[ne]; 37 add(from,to,flow,cost); 38 add(to,from,0,-cost); 39 } 40 41 inline bool spfa() 42 { 43 memset(d,0x3f,sizeof(d)); 44 flag.reset(); 45 int op=0,cls=1; 46 q[1]=s; 47 d[s]=0; 48 flag[s]=1; 49 while (op != cls) 50 { 51 op=op == maxn-1 ? 0 : op+1; 52 int x=q[op]; 53 for (edge *p=head[x];p;p=p->next) 54 if (p->flow && d[p->to] > d[x]+p->cost) 55 { 56 d[p->to]=d[x]+p->cost; 57 prev[p->to]=p->part; 58 if (!flag[p->to]) 59 { 60 if (op != cls) 61 { 62 int now=op == maxn-1 ? 0 : op+1; 63 if (d[p->to] < d[q[now]]) 64 { 65 q[op]=p->to; 66 op=op == 0 ? maxn-1 : op-1; 67 } 68 else 69 { 70 cls=cls == maxn-1 ? 0 : cls+1; 71 q[cls]=p->to; 72 } 73 } 74 else 75 { 76 cls=cls == maxn-1 ? 0 : cls+1; 77 q[cls]=p->to; 78 } 79 flag[p->to]=1; 80 } 81 } 82 flag[x]=0; 83 } 84 return d[t] != inf; 85 } 86 87 inline int agument() 88 { 89 int f=inf,ans=0; 90 for (edge *p=prev[t];p;p=prev[p->to]) 91 f=min(f,p->part->flow); 92 for (edge *p=prev[t];p;p=prev[p->to]) 93 { 94 p->flow+=f; 95 p->part->flow-=f; 96 ans+=p->part->cost*f; 97 } 98 return ans; 99 } 100 101 inline int min_cost() 102 { 103 int ans=0; 104 while (spfa()) 105 ans+=agument(); 106 return ans; 107 } 108 109 int need[maxn]; 110 111 int main() 112 { 113 int n,m; 114 scanf("%d%d",&n,&m); 115 for (int i=1;i<=n;i++) 116 scanf("%d",&need[i]); 117 for (int i=1;i<=m;i++) 118 { 119 int x,y,z; 120 scanf("%d%d%d",&x,&y,&z); 121 add_edge(x,y+1,inf,z); 122 } 123 need[n+1]=0; 124 for (int i=1;i<=n+1;i++) 125 { 126 int now=need[i]-need[i-1]; 127 if (now >= 0) 128 add_edge(s,i,now,0); 129 else 130 add_edge(i,t,-now,0); 131 if (i > 1) 132 add_edge(i,i-1,inf,0); 133 } 134 printf("%d\n",min_cost()); 135 return 0; 136 }
bzoj1066
水的不能再水的网络流
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1010 8 #define maxm 100010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow; 16 edge *part,*next; 17 }e[maxm<<1],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 d[p->to]=d[x]+1; 51 q[++cls]=p->to; 52 } 53 } 54 return ~d[t]; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 inline int sqr(int x) 84 { 85 return x*x; 86 } 87 88 int pos[50][50]; 89 int map[50][50]; 90 91 int main() 92 { 93 int n,m,d; 94 scanf("%d%d%d",&n,&m,&d); 95 for (int i=1;i<=n;i++) 96 for (int j=1;j<=m;j++) 97 { 98 pos[i][j]=(i-1)*m+j; 99 char ch; 100 while (ch=getchar(),ch > '9' || ch < '0'); 101 map[i][j]=ch-'0'; 102 if (map[i][j]) 103 add_edge(pos[i][j],pos[i][j]+n*m,map[i][j]); 104 } 105 for (int i=1;i<=n;i++) 106 for (int j=1;j<=m;j++) 107 if (map[i][j]) 108 { 109 for (int k=-d;k<=d;k++) 110 for (int l=-d;l<=d;l++) 111 { 112 int x=i+k,y=j+l; 113 if (x <= 0 || y <= 0 || x > n || y > m) 114 continue; 115 if (map[x][y]) 116 if (sqr(i-x)+sqr(j-y) <= d*d) 117 add_edge(pos[i][j]+n*m,pos[x][y],inf); 118 } 119 if (i <= d || n-i+1 <= d || j <= d || m-j+1 <= d) 120 add_edge(pos[i][j]+n*m,t,inf); 121 } 122 int sum=0; 123 for (int i=1;i<=n;i++) 124 for (int j=1;j<=m;j++) 125 { 126 char ch; 127 while (ch=getchar(),ch != '.' && ch != 'L'); 128 if (ch == 'L') 129 { 130 sum++; 131 add_edge(s,pos[i][j],1); 132 } 133 } 134 printf("%d\n",sum-dinic()); 135 return 0; 136 }
bzoj1067
情况比较蛋疼的st。。。还记得那年的本地AC提交RE吗?就是这道题。。。
1 #include<cstdio> 2 3 const int maxn=50010; 4 5 int f[maxn][30],bit[30],n,m; 6 7 struct rei 8 { 9 int y,v; 10 void init() 11 { 12 scanf("%d%d",&y,&v); 13 } 14 }z[maxn]; 15 16 inline int max(int a,int b) 17 { 18 if (a > b) 19 return a; 20 return b; 21 } 22 23 inline int find(int y) 24 { 25 int l=0,r=n; 26 while (l+1!=r) 27 { 28 int m=(l+r)>>1; 29 if (z[m].y>=y) r=m; 30 else l=m; 31 } 32 return r; 33 } 34 35 inline int query(int l,int r) 36 { 37 if (l>r) return -1; 38 int now=0; 39 while (l+bit[now]-1<=r) 40 now++; 41 now--; 42 return max(f[l][now],f[r-bit[now]+1][now]); 43 } 44 45 int main() 46 { 47 scanf("%d",&n); 48 for (int a=1;a<=n;a++) 49 z[a].init(); 50 bit[0]=1; 51 for (int a=1;a<=20;a++) 52 bit[a]=bit[a-1]*2; 53 for (int a=1;a<=n;a++) 54 f[a][0]=z[a].v; 55 for (int a=1;a<=20;a++) 56 if (bit[a]>n) break; 57 else 58 { 59 for (int b=1;b+bit[a]-1<=n;b++) 60 f[b][a]=max(f[b][a-1],f[b+bit[a-1]][a-1]); 61 } 62 scanf("%d",&m); 63 for (int a=1;a<=m;a++) 64 { 65 int x,y; 66 scanf("%d%d",&y,&x); 67 int l=find(y); 68 int r=find(x); 69 if (z[l].y==y && z[r].y==x) 70 { 71 if (z[l].v<z[r].v) printf("false\n"); 72 else 73 { 74 int nowv=query(l+1,r-1); 75 if (nowv>=z[r].v) printf("false\n"); 76 else 77 { 78 if (r-l+1==z[r].y-z[l].y+1) printf("true\n"); 79 else printf("maybe\n"); 80 } 81 } 82 } 83 else 84 { 85 if (z[l].y==y) 86 { 87 while (z[r].y>x) 88 r--; 89 int nowv=query(l+1,r); 90 if (nowv>=z[l].v) printf("false\n"); 91 else printf("maybe\n"); 92 } 93 else 94 { 95 if (z[r].y==x) 96 { 97 while (z[l].y<y) 98 l++; 99 int nowv=query(l,r-1); 100 if (nowv>=z[r].v) printf("false\n"); 101 else printf("maybe\n"); 102 } 103 else printf("maybe\n"); 104 } 105 } 106 } 107 108 return 0; 109 }
bzoj1070
很不错的拆点费用流,考虑每个人第几个修某辆车对总时间的贡献
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 1010 5 #define maxm 1000010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int to,flow,cost; 11 edge *next,*part; 12 }e[maxm],*head[maxn],*prev[maxn]; 13 14 int s=0,t=maxn-1; 15 int n,m,ne=0; 16 int q[maxn],d[maxn]; 17 int time[10][80]; 18 bool flag[maxn]; 19 20 inline int min(int a,int b) 21 { 22 return a < b ? a : b; 23 } 24 25 inline void add(int from,int to,int flow,int cost) 26 { 27 e[ne].to=to; 28 e[ne].flow=flow; 29 e[ne].cost=cost; 30 e[ne].next=head[from]; 31 head[from]=&e[ne++]; 32 } 33 34 inline void add_edge(int from,int to,int flow,int cost) 35 { 36 e[ne].part=&e[ne+1]; 37 e[ne+1].part=&e[ne]; 38 add(from,to,flow,cost); 39 add(to,from,0,-cost); 40 } 41 42 inline bool spfa() 43 { 44 int op=0,cls=1; 45 memset(flag,0,sizeof(flag)); 46 memset(d,0x3f,sizeof(d)); 47 flag[s]=1; 48 d[s]=0; 49 q[1]=s; 50 while (op != cls) 51 { 52 op++; 53 if (op == maxn) 54 op=0; 55 int x=q[op]; 56 flag[x]=0; 57 for (edge *p=head[x];p;p=p->next) 58 if (p->flow && d[x]+p->cost < d[p->to]) 59 { 60 d[p->to]=d[x]+p->cost; 61 prev[p->to]=p->part; 62 if (!flag[p->to]) 63 { 64 cls++; 65 if (cls == maxn) 66 cls=0; 67 q[cls]=p->to; 68 flag[p->to]=1; 69 } 70 } 71 } 72 return d[t] != inf; 73 } 74 75 inline int agument() 76 { 77 int f=inf,cost=0; 78 for (edge *p=prev[t];p;p=prev[p->to]) 79 f=min(f,p->part->flow); 80 for (edge *p=prev[t];p;p=prev[p->to]) 81 { 82 p->part->flow-=f; 83 p->flow+=f; 84 cost+=f*p->part->cost; 85 } 86 return cost; 87 } 88 89 inline int min_cost() 90 { 91 int out=0; 92 while (spfa()) 93 out+=agument(); 94 return out; 95 } 96 97 int main() 98 { 99 scanf("%d%d",&m,&n); 100 for (int i=1;i<=n;i++) 101 for (int j=1;j<=m;j++) 102 scanf("%d",&time[j][i]); 103 for (int i=1;i<=m;i++) 104 for (int j=1;j<=n;j++) 105 for (int k=1;k<=n;k++) 106 add_edge((j-1)*m+i,k+m*n,1,j*time[i][k]); 107 for (int i=1;i<=m;i++) 108 for (int j=1;j<=n;j++) 109 add_edge(s,(j-1)*m+i,1,0); 110 for (int i=1;i<=n;i++) 111 add_edge(m*n+i,t,1,0); 112 printf("%.2lf\n",(double)min_cost()/n); 113 return 0; 114 }
bzoj1076
状态压缩DP求期望,倒着做
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 110 7 #define maxm 16 8 9 double f[maxn][1<<15]; 10 int need[maxm]; 11 double v[maxm]; 12 int bit[21]; 13 14 int main() 15 { 16 bit[0]=1; 17 for (int i=1;i<=20;i++) 18 bit[i]=bit[i-1]+bit[i-1]; 19 int n,m; 20 scanf("%d%d",&n,&m); 21 for (int i=1;i<=m;i++) 22 { 23 scanf("%lf",&v[i]); 24 int t; 25 while (1) 26 { 27 scanf("%d",&t); 28 if (!t) 29 break; 30 need[i]|=bit[t-1]; 31 } 32 } 33 for (int i=n;i;i--) 34 for (int j=0;j<bit[m];j++) 35 { 36 f[i][j]=0; 37 for (int k=1;k<=m;k++) 38 if ((j&need[k]) == need[k]) 39 f[i][j]+=max(f[i+1][j],f[i+1][j|bit[k-1]]+v[k]); 40 else 41 f[i][j]+=f[i+1][j]; 42 f[i][j]/=(double)m; 43 } 44 printf("%.6lf\n",f[1][0]); 45 return 0; 46 }
bzoj1079
我写过的复杂度看起来最高的DP,五维的状态。。。
1 #include <cstdio> 2 3 #define maxn 16 4 #define mod 1000000007 5 6 #ifdef unix 7 #define LL "%lld" 8 #else 9 #define LL "%I64d" 10 #endif 11 12 long long now[maxn]; 13 long long f[maxn][maxn][maxn][maxn][maxn][6]; 14 15 long long fdp(long long a,long long b,long long c,long long d,long long e,long long last) 16 { 17 if (a+b+c+d+e == 0) 18 return 1; 19 if (f[a][b][c][d][e][last]) 20 return f[a][b][c][d][e][last]; 21 long long ans=0; 22 if (d > 0) 23 (ans+=(d-(last == 5))*fdp(a,b,c+1,d-1,e,4))%=mod; 24 if (c > 0) 25 (ans+=(c-(last == 4))*fdp(a,b+1,c-1,d,e,3))%=mod; 26 if (b > 0) 27 (ans+=(b-(last == 3))*fdp(a+1,b-1,c,d,e,2))%=mod; 28 if (a > 0) 29 (ans+=(a-(last == 2))*fdp(a-1,b,c,d,e,1))%=mod; 30 if (e > 0) 31 (ans+=e*fdp(a,b,c,d+1,e-1,5))%=mod; 32 return f[a][b][c][d][e][last]=ans; 33 } 34 35 int main() 36 { 37 long long n; 38 scanf(LL,&n); 39 for (long long i=1;i<=n;i++) 40 { 41 long long x; 42 scanf(LL,&x); 43 now[x]++; 44 } 45 printf(LL,fdp(now[1],now[2],now[3],now[4],now[5],0)%mod); 46 return 0; 47 }
bzoj1088
不要去想真的扫雷。。。枚举开头两个雷的状态,然后就可以递推了。。。
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 10010 5 6 int n; 7 bool f[maxn]; 8 int a[maxn]; 9 10 inline bool check() 11 { 12 for (int i=2;i<n;i++) 13 { 14 if (a[i] < f[i-1]+f[i]) 15 return 0; 16 if (a[i] == f[i-1]+f[i]) 17 f[i+1]=0; 18 if (a[i] == f[i-1]+f[i]+1) 19 f[i+1]=1; 20 if (a[i] > f[i-1]+f[i]+1) 21 return 0; 22 } 23 if (a[n] == f[n-1]+f[n]) 24 return 1; 25 return 0; 26 } 27 28 int main() 29 { 30 scanf("%d",&n); 31 for (int i=1;i<=n;i++) 32 scanf("%d",&a[i]); 33 int ans=0; 34 if (a[1] == 0) 35 { 36 f[1]=f[2]=0; 37 ans+=check(); 38 } 39 else 40 { 41 if (a[1] == 1) 42 { 43 f[1]=1,f[2]=0; 44 ans+=check(); 45 memset(f,0,sizeof(f)); 46 f[1]=0,f[2]=1; 47 ans+=check(); 48 } 49 else 50 { 51 f[1]=f[2]=1; 52 ans+=check(); 53 } 54 } 55 printf("%d\n",ans); 56 return 0; 57 }
bzoj1089
treedp+高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #ifdef unix 11 #define ll "%lld" 12 #else 13 #define ll "%I64d" 14 #endif 15 class wkint { 16 private: 17 long long a[1510]; 18 int len; 19 public: 20 wkint(); 21 wkint(int t); 22 void read(); 23 void print(); 24 wkint operator + (const wkint &t) const; 25 wkint operator - (const wkint &t) const; 26 wkint operator * (const wkint &t) const; 27 wkint operator * (const int &t) const; 28 wkint operator ^ (const int &t) const; 29 wkint operator / (const int &t) const; 30 int operator % (const int &t) const; 31 bool operator < (const wkint &t) const; 32 bool operator > (const wkint &t) const; 33 bool operator == (const wkint &t) const; 34 bool operator != (const wkint &t) const; 35 }; 36 37 wkint::wkint() { 38 len = 1; 39 memset(a, 0, sizeof(a)); 40 } 41 wkint::wkint(int t) { 42 len = 1; 43 a[1] = t; 44 } 45 void wkint::read() { 46 string tmp; 47 cin >> tmp; 48 int lenT = tmp.length(); 49 len = (lenT + 7) / 8; 50 int ptr = len, now = 0; 51 for (int i = 0; i < lenT; i ++) { 52 now *= 10; now += (int)(tmp[i] - '0'); 53 if (!((lenT - i - 1) % 8)) { 54 a[ptr] = now; 55 now = 0; 56 ptr --; 57 } 58 } 59 } 60 void wkint::print() { 61 printf(ll, a[len]); 62 for (int i = len - 1; i >= 1; i --) { 63 int ws = (int)log10((long double)(a[i] + 1)) + 1; 64 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 65 printf(ll, a[i]); 66 } 67 printf("\n"); 68 } 69 wkint wkint::operator + (const wkint &t) const { 70 wkint res; 71 int maxlen = max(t.len, len); 72 for (int i = 1; i <= maxlen; i ++) { 73 res.a[i] += a[i] + t.a[i]; 74 if (res.a[i] >= 100000000) { 75 res.a[i + 1] += res.a[i] / 100000000; 76 res.a[i] %= 100000000; 77 } 78 } 79 if (res.a[maxlen + 1]) maxlen ++; 80 res.len = maxlen; 81 return res; 82 } 83 wkint wkint::operator - (const wkint &t) const { 84 wkint res; 85 int maxlen = max(t.len, len); 86 for (int i = 1; i <= maxlen; i ++) { 87 res.a[i] += a[i] - t.a[i]; 88 if (res.a[i] < 0) { 89 res.a[i + 1] -= 1; 90 res.a[i] += 100000000; 91 } 92 } 93 while (!res.a[maxlen]) maxlen --; 94 res.len = maxlen; 95 return res; 96 } 97 wkint wkint::operator * (const wkint &t) const { 98 wkint res; 99 int maxlen = t.len + len - 1; 100 for (int i = 1; i <= len; i ++) 101 for (int j = 1; j <= t.len; j ++) { 102 res.a[i + j - 1] += a[i] * t.a[j]; 103 } 104 for (int i = 1; i <= maxlen; i ++) 105 if (res.a[i] > 100000000) { 106 res.a[i + 1] += res.a[i] / 100000000; 107 res.a[i] %= 100000000; 108 } 109 if (res.a[maxlen + 1]) maxlen ++; 110 res.len = maxlen; 111 return res; 112 } 113 wkint wkint::operator * (const int &t) const { 114 wkint res; 115 res.len = len; 116 for (int i = 1; i <= len; i ++) { 117 res.a[i] += a[i] * t; 118 if (res.a[i] > 100000000) { 119 res.a[i + 1] += res.a[i] / 100000000; 120 res.a[i] %= 100000000; 121 } 122 } 123 if (res.a[res.len + 1]) res.len ++; 124 return res; 125 } 126 wkint wkint::operator ^ (const int &t) const { 127 wkint res = wkint(1), tmp; 128 int now = t; 129 memcpy(tmp.a, a, sizeof(a)); 130 tmp.len = len; 131 while (now) { 132 if (now & 1) res = res * tmp; 133 tmp = tmp * tmp; 134 now >>= 1; 135 } 136 return res; 137 } 138 wkint wkint::operator / (const int &t) const { 139 wkint res; 140 long long now = 0; 141 res.len = len; 142 for (int i = len; i >= 1; i --) { 143 now *= 100000000, now += a[i]; 144 if (now < t) { 145 res.a[i] = 0; 146 } else { 147 res.a[i] = now / t; 148 now %= t; 149 } 150 } 151 while (!res.a[res.len]) res.len --; 152 return res; 153 } 154 int wkint::operator % (const int &t) const { 155 long long now = 0; 156 for (int i = len; i >= 1; i --) { 157 now *= 100000000, now += a[i]; 158 now %= t; 159 } 160 return (int)now; 161 } 162 bool wkint::operator < (const wkint &t) const { 163 if (len < t.len) return true; 164 if (len > t.len) return false; 165 for (int i = len; i >= 1; i --) 166 if (a[i] < t.a[i]) { 167 return true; 168 } else if (a[i] > t.a[i]) { 169 return false; 170 } 171 return false; 172 } 173 bool wkint::operator > (const wkint &t) const { 174 if (len > t.len) return true; 175 if (len < t.len) return false; 176 for (int i = len; i >= 1; i --) 177 if (a[i] > t.a[i]) { 178 return true; 179 } else if (a[i] < t.a[i]) { 180 return false; 181 } 182 return false; 183 } 184 bool wkint::operator == (const wkint &t) const { 185 if (t.len != len) return false; 186 for (int i = 1; i <= len; i ++) 187 if (a[i] != t.a[i]) { 188 return false; 189 } 190 return true; 191 } 192 bool wkint::operator != (const wkint &t) const { 193 if (t.len != len) return true; 194 for (int i = 1; i <= len; i ++) 195 if (a[i] != t.a[i]) { 196 return true; 197 } 198 return false; 199 } 200 201 wkint f[40]; 202 203 wkint pow(wkint a,int b) 204 { 205 wkint ans=1; 206 for (;b;b>>=1) 207 { 208 if (b&1) 209 ans=ans*a; 210 a=a*a; 211 } 212 return ans; 213 } 214 215 int main() 216 { 217 int n,d; 218 scanf("%d%d",&n,&d); 219 if (d < 2) 220 { 221 puts("1"); 222 return 0; 223 } 224 f[0]=1; 225 f[1]=2; 226 for (int i=2;i<=d;i++) 227 f[i]=pow(f[i-1],n)+1; 228 f[d]=f[d]-f[d-1]; 229 f[d].print(); 230 return 0; 231 }
bzoj1093
tarjan缩点然后DFS(虽然很多人认为那是DP。。。)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 100010 8 #define maxm 1000010 9 10 struct edge 11 { 12 int to; 13 edge *next; 14 }e[maxm],*head[maxn]; 15 16 int time=0; 17 int ne=0; 18 int p; 19 int cnt=0; 20 int from[maxm],to[maxm],pos[maxm],flag[maxm]; 21 int size[maxn]; 22 int dfn[maxn],low[maxn],sta[maxn],belong[maxn],top=0; 23 bool vis[maxn]; 24 int f[maxn],q[maxn],g[maxn],in[maxn]; 25 26 inline void inc(int &a,int b) 27 { 28 a+=b; 29 while (a >= p) 30 a-=p; 31 } 32 33 inline void read(int &x) 34 { 35 char ch; 36 while (ch=getchar(),ch > '9' || ch < '0'); 37 x=ch-'0'; 38 while (ch=getchar(),ch <= '9' && ch >= '0') 39 x=(x<<3)+x+x+ch-'0'; 40 } 41 42 inline void add_edge(int from,int to) 43 { 44 e[ne].to=to; 45 e[ne].next=head[from]; 46 head[from]=&e[ne++]; 47 } 48 49 inline void tarjan(int now) 50 { 51 dfn[now]=low[now]=++time; 52 sta[++top]=now; 53 vis[now]=1; 54 for (edge *p=head[now];p;p=p->next) 55 if (!dfn[p->to]) 56 { 57 tarjan(p->to); 58 low[now]=min(low[now],low[p->to]); 59 } 60 else 61 if (vis[p->to]) 62 low[now]=min(low[now],dfn[p->to]); 63 if (dfn[now] == low[now]) 64 { 65 int p; 66 cnt++; 67 do 68 { 69 p=sta[top--]; 70 vis[p]=0; 71 belong[p]=cnt; 72 size[cnt]++; 73 } 74 while (p != now); 75 } 76 } 77 78 inline void dfs(int now) 79 { 80 if (f[now]) 81 return; 82 int _max=0; 83 for (edge *p=head[now];p;p=p->next) 84 { 85 dfs(p->to); 86 f[now]=max(f[now],f[p->to]+size[now]); 87 } 88 if (!f[now]) 89 { 90 f[now]=size[now]; 91 g[now]=1; 92 } 93 for (edge *p=head[now];p;p=p->next) 94 if (f[p->to]+size[now] == f[now]) 95 inc(g[now],g[p->to]); 96 } 97 98 inline bool cmp(const int a,const int b) 99 { 100 return (belong[from[a]] < belong[from[b]]) || (belong[from[a]] == belong[from[b]] && belong[to[a]] < belong[to[b]]); 101 } 102 103 int main() 104 { 105 int n,m; 106 read(n); 107 read(m); 108 read(p); 109 for (int i=1;i<=m;i++) 110 { 111 read(from[i]); 112 read(to[i]); 113 add_edge(from[i],to[i]); 114 pos[i]=i; 115 flag[i]=1; 116 } 117 for (int i=1;i<=n;i++) 118 if (!dfn[i]) 119 tarjan(i); 120 memset(head,0,sizeof(head)); 121 memset(vis,0,sizeof(vis)); 122 ne=0; 123 sort(pos+1,pos+m+1,cmp); 124 for (int i=1;i<=m;i++) 125 { 126 int x=pos[i]; 127 if (belong[from[x]] == belong[to[x]]) 128 flag[x]=0; 129 else 130 if (belong[from[x]] == belong[from[pos[i-1]]] && belong[to[x]] == belong[to[pos[i-1]]]) 131 flag[x]=0; 132 } 133 for (int i=1;i<=m;i++) 134 if (flag[i]) 135 { 136 add_edge(belong[from[i]],belong[to[i]]); 137 in[belong[to[i]]]++; 138 } 139 for (int i=1;i<=cnt;i++) 140 if (!in[i]) 141 dfs(i); 142 int _max=0; 143 for (int i=1;i<=cnt;i++) 144 _max=max(_max,f[i]); 145 printf("%d\n",_max); 146 int ans=0; 147 for (int i=1;i<=cnt;i++) 148 if (f[i] == _max) 149 inc(ans,g[i]); 150 printf("%d\n",ans); 151 return 0; 152 }
bzoj1096
斜率优化的DP
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 #ifdef unix 6 #define LL "%lld" 7 #else 8 #define LL "%I64d" 9 #endif 10 11 long long dp[maxn],sum[maxn],a[maxn],c[maxn],l[maxn]; 12 long long q[maxn]; 13 14 inline void read(long long &x) 15 { 16 char ch; 17 while (ch=getchar(),ch > '9' || ch < '0'); 18 x=ch-'0'; 19 while (ch=getchar(),ch <= '9' && ch >= '0') 20 x=(x<<3)+x+x+ch-'0'; 21 } 22 23 inline long long calc(long long x,long long y) 24 { 25 return dp[x]-dp[y]+a[x]-a[y]; 26 } 27 28 int main() 29 { 30 long long n; 31 read(n); 32 for (long long i=1;i<=n;i++) 33 { 34 read(l[i]); 35 read(sum[i]); 36 read(c[i]); 37 a[i]=l[i]*sum[i]; 38 a[i]+=a[i-1]; 39 sum[i]+=sum[i-1]; 40 } 41 long long op=0,cls=0; 42 for (long long i=1;i<=n;i++) 43 { 44 while (op != cls && calc(q[op+1],q[op]) <= l[i]*(sum[q[op+1]]-sum[q[op]])) 45 op++; 46 dp[i]=dp[q[op]]+(sum[i]-sum[q[op]])*l[i]-(a[i]-a[q[op]])+c[i]; 47 while (op != cls && calc(i,q[cls])*(sum[q[cls]]-sum[q[cls-1]]) < calc(q[cls],q[cls-1])*(sum[i]-sum[q[cls]])) 48 cls--; 49 q[++cls]=i; 50 } 51 printf(LL,dp[n]); 52 return 0; 53 }
bzoj1103
DFS序上建立树状数组
1 #include <cstdio> 2 3 #define maxn 250010 4 5 struct edge 6 { 7 int to; 8 edge *next; 9 }e[maxn],*head[maxn]; 10 11 int ne=0; 12 13 inline void read(int &x) 14 { 15 x=0; 16 char ch; 17 while (ch=getchar(),ch > '9' || ch < '0'); 18 x=ch-'0'; 19 while (ch=getchar(),ch <= '9' && ch >= '0') 20 x=(x<<3)+x+x+ch-'0'; 21 } 22 23 inline void add_edge(int from,int to) 24 { 25 e[ne].to=to; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 int n; 31 int l[maxn],r[maxn],bit[maxn]; 32 33 void dfs(int now) 34 { 35 l[now]=++ne; 36 for (edge *p=head[now];p;p=p->next) 37 dfs(p->to); 38 r[now]=ne; 39 } 40 41 inline void bit_update(int now,int add) 42 { 43 for (;now<=n;now+=now&-now) 44 bit[now]+=add; 45 } 46 47 inline int query(int now) 48 { 49 int ans=0; 50 for (;now;now-=now&-now) 51 ans+=bit[now]; 52 return ans; 53 } 54 55 int main() 56 { 57 read(n); 58 for (int i=1;i<n;i++) 59 { 60 int x,y; 61 read(x); 62 read(y); 63 if (x > y) 64 x^=y^=x^=y; 65 add_edge(x,y); 66 } 67 ne=0; 68 dfs(1); 69 for (int i=1;i<=n;i++) 70 bit[i]=i&-i; 71 for (int i=1;i<=n;i++) 72 bit_update(r[i]+1,-1); 73 int m; 74 read(m); 75 for (int i=1;i<=n+m-1;i++) 76 { 77 char s[2]; 78 scanf("%s",s); 79 if (s[0] == 'W') 80 { 81 int x; 82 read(x); 83 printf("%d\n",query(l[x])-1); 84 } 85 else 86 { 87 int x,y; 88 read(x); 89 read(y); 90 if (x < y) 91 x^=y^=x^=y; 92 bit_update(l[x],-1); 93 bit_update(r[x]+1,1); 94 } 95 } 96 return 0; 97 }
bzoj1143
处理出每个点能到达的所有点,然后拆点二分图最大独立集
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 510 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 bool map[maxn][maxn]; 22 bool flag[maxn]; 23 24 inline void add(int from,int to,int flow) 25 { 26 e[ne].to=to; 27 e[ne].flow=flow; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow); 37 add(to,from,0); 38 } 39 40 inline void add_edge(int from,int to) 41 { 42 e[ne].to=to; 43 e[ne].next=head[from]; 44 head[from]=&e[ne++]; 45 } 46 47 inline bool bfs() 48 { 49 int op=0,cls=1; 50 memset(d,-1,sizeof(d)); 51 q[1]=s; 52 d[s]=0; 53 while (op != cls) 54 { 55 int x=q[++op]; 56 for (edge *p=head[x];p;p=p->next) 57 if (p->flow && d[p->to] == -1) 58 { 59 q[++cls]=p->to; 60 d[p->to]=d[x]+1; 61 } 62 } 63 return ~d[t]; 64 } 65 66 int dfs(int now,int now_flow) 67 { 68 if (now == t) 69 return now_flow; 70 int out=now_flow; 71 for (edge *p=head[now];p;p=p->next) 72 if (p->flow && d[p->to] == d[now]+1 && out) 73 { 74 int f=dfs(p->to,min(p->flow,out)); 75 p->flow-=f; 76 p->part->flow+=f; 77 out-=f; 78 } 79 if (out == now_flow) 80 d[now]=-1; 81 return now_flow-out; 82 } 83 84 inline int dinic() 85 { 86 int ans=0; 87 while (bfs()) 88 ans+=dfs(s,inf); 89 return ans; 90 } 91 92 inline void bfs(int now) 93 { 94 memset(flag,0,sizeof(flag)); 95 int op=0,cls=1; 96 q[1]=now; 97 flag[now]=1; 98 while (op != cls) 99 { 100 int x=q[++op]; 101 for (edge *p=head[x];p;p=p->next) 102 if (!flag[p->to]) 103 { 104 q[++cls]=p->to; 105 map[now][p->to]=1; 106 flag[p->to]=1; 107 } 108 } 109 } 110 111 int main() 112 { 113 int n,m; 114 scanf("%d%d",&n,&m); 115 for (int i=1;i<=m;i++) 116 { 117 int x,y; 118 scanf("%d%d",&x,&y); 119 add_edge(x,y); 120 } 121 for (int i=1;i<=n;i++) 122 bfs(i); 123 memset(head,0,sizeof(head)); 124 ne=0; 125 for (int i=1;i<=n;i++) 126 for (int j=1;j<=n;j++) 127 if (map[i][j]) 128 add_edge(i,j+n,1); 129 for (int i=1;i<=n;i++) 130 { 131 add_edge(s,i,1); 132 add_edge(i+n,t,1); 133 } 134 printf("%d\n",n-dinic()); 135 return 0; 136 }
bzoj1146
当年的做法是树链剖分树套树,现在可以在DFS序上建立树状数组套主席树来解决,orz rank1的大刷子crf
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 80010 8 9 struct Node 10 { 11 int size; 12 Node* s[2]; 13 }t[maxn*160],*root[maxn],null,*L[100],*R[100]; 14 15 struct edge 16 { 17 int to; 18 edge *next; 19 }e[maxn<<1],*head[maxn]; 20 21 struct query 22 { 23 int to,num; 24 query *next; 25 }que[maxn<<1],*begin[maxn]; 26 27 int n,m,size,ne=0,lsize,rsize; 28 int a[maxn],b[maxn<<1],q[maxn][3],lca[maxn]; 29 int l[maxn],r[maxn]; 30 int anc[maxn],f[maxn],fa[maxn],rank[maxn]; 31 bool flag[maxn]; 32 33 inline void add_edge(int from,int to) 34 { 35 e[ne].to=to; 36 e[ne].next=head[from]; 37 head[from]=&e[ne++]; 38 } 39 40 inline void add_query(int from,int to,int num) 41 { 42 que[ne].to=to; 43 que[ne].num=num; 44 que[ne].next=begin[from]; 45 begin[from]=&que[ne++]; 46 } 47 48 inline void read(int &x) 49 { 50 char ch; 51 while (ch=getchar(),ch > 57 || ch < 48); 52 x=ch-48; 53 while (ch=getchar(),ch <= 57 && ch >= 48) 54 x=(x<<3)+x+x+ch-48; 55 } 56 57 int find(int now) 58 { 59 if (f[now] == now) 60 return now; 61 return f[now]=find(f[now]); 62 } 63 64 inline void _union(int x,int y) 65 { 66 int a=find(x); 67 int b=find(y); 68 if (a == b) 69 return; 70 if (rank[a] <= rank[b]) 71 { 72 f[a]=b; 73 rank[b]+=rank[a]; 74 } 75 else 76 { 77 f[b]=a; 78 rank[a]+=rank[b]; 79 } 80 } 81 82 void dfs(int now) 83 { 84 f[now]=now; 85 anc[now]=now; 86 flag[now]=1; 87 l[now]=++ne; 88 for (edge *p=head[now];p;p=p->next) 89 if (!flag[p->to]) 90 { 91 dfs(p->to); 92 fa[p->to]=now; 93 _union(now,p->to); 94 anc[find(now)]=now; 95 } 96 for (query *q=begin[now];q;q=q->next) 97 if (flag[q->to]) 98 lca[q->num]=anc[find(q->to)]; 99 r[now]=ne; 100 } 101 102 inline void update(Node* now,int val,int flag) 103 { 104 int l=1,r=size; 105 while (1) 106 { 107 now->size+=flag; 108 if (l == r) 109 return; 110 int mid=(l+r)>>1; 111 if (val <= mid) 112 { 113 if (now->s[0] == &null) 114 { 115 now->s[0]=&t[ne++]; 116 now->s[0]->s[0]=now->s[0]->s[1]=&null; 117 now->s[0]->size=0; 118 } 119 now=now->s[0]; 120 r=mid; 121 } 122 else 123 { 124 if (now->s[1] == &null) 125 { 126 now->s[1]=&t[ne++]; 127 now->s[1]->s[0]=now->s[1]->s[1]=&null; 128 now->s[1]->size=0; 129 } 130 now=now->s[1]; 131 l=mid+1; 132 } 133 } 134 } 135 136 inline void bit_update(int now,int val,int flag) 137 { 138 for (;now<=n;now+=now&-now) 139 update(root[now],val,flag); 140 } 141 142 inline int query(int x,int y,int lca,int flca,int k) 143 { 144 lsize=rsize=0; 145 x=l[x]; 146 y=l[y]; 147 lca=l[lca]; 148 flca=l[flca]; 149 int del=0; 150 for (;x>0;x-=x&-x) 151 { 152 R[++rsize]=root[x]; 153 del+=R[rsize]->size; 154 } 155 for (;y>0;y-=y&-y) 156 { 157 R[++rsize]=root[y]; 158 del+=R[rsize]->size; 159 } 160 for (;lca>0;lca-=lca&-lca) 161 { 162 L[++lsize]=root[lca]; 163 del-=L[lsize]->size; 164 } 165 for (;flca>0;flca-=flca&-flca) 166 { 167 L[++lsize]=root[flca]; 168 del-=L[lsize]->size; 169 } 170 if (del < k) 171 return -1; 172 int l=1,r=size; 173 while (1) 174 { 175 if (l == r) 176 return l; 177 int mid=(l+r)>>1; 178 del=0; 179 for (int i=1;i<=rsize;i++) 180 del+=R[i]->s[1]->size; 181 for (int i=1;i<=lsize;i++) 182 del-=L[i]->s[1]->size; 183 if (k <= del) 184 { 185 for (int i=1;i<=lsize;i++) 186 L[i]=L[i]->s[1]; 187 for (int i=1;i<=rsize;i++) 188 R[i]=R[i]->s[1]; 189 l=mid+1; 190 } 191 else 192 { 193 for (int i=1;i<=lsize;i++) 194 L[i]=L[i]->s[0]; 195 for (int i=1;i<=rsize;i++) 196 R[i]=R[i]->s[0]; 197 k-=del; 198 r=mid; 199 } 200 } 201 } 202 203 int main() 204 { 205 // freopen("1.in","r",stdin); 206 // freopen("1.out","w",stdout); 207 read(n); 208 read(m); 209 for (int i=1;i<=n;i++) 210 { 211 read(a[i]); 212 b[i]=a[i]; 213 } 214 size=n; 215 for (int i=1;i<n;i++) 216 { 217 int x,y; 218 read(x); 219 read(y); 220 add_edge(x,y); 221 add_edge(y,x); 222 } 223 ne=0; 224 for (int i=1;i<=m;i++) 225 { 226 read(q[i][0]); 227 read(q[i][1]); 228 read(q[i][2]); 229 if (!q[i][0]) 230 b[++size]=q[i][2]; 231 else 232 { 233 add_query(q[i][1],q[i][2],i); 234 add_query(q[i][2],q[i][1],i); 235 } 236 } 237 ne=0; 238 sort(b+1,b+size+1); 239 size=unique(b+1,b+size+1)-b-1; 240 for (int i=1;i<=n;i++) 241 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 242 null.s[0]=null.s[1]=&null; 243 null.size=0; 244 dfs(1); 245 ne=0; 246 for (int i=0;i<=n;i++) 247 { 248 root[i]=&t[ne++]; 249 root[i]->s[0]=root[i]->s[1]=&null; 250 root[i]->size=0; 251 } 252 for (int i=1;i<=n;i++) 253 { 254 bit_update(l[i],a[i],1); 255 bit_update(r[i]+1,a[i],-1); 256 } 257 for (int i=1;i<=m;i++) 258 { 259 if (!q[i][0]) 260 { 261 bit_update(l[q[i][1]],a[q[i][1]],-1); 262 bit_update(r[q[i][1]]+1,a[q[i][1]],1); 263 a[q[i][1]]=lower_bound(b+1,b+size+1,q[i][2])-b; 264 bit_update(l[q[i][1]],a[q[i][1]],1); 265 bit_update(r[q[i][1]]+1,a[q[i][1]],-1); 266 } 267 else 268 { 269 int ans=query(q[i][1],q[i][2],lca[i],fa[lca[i]],q[i][0]); 270 if (ans != -1) 271 printf("%d\n",b[ans]); 272 else 273 printf("invalid request!\n"); 274 } 275 } 276 return 0; 277 }
bzoj1179
tarjan缩点后做最长路
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 500010 8 #define maxm 1000010 9 10 struct edge 11 { 12 int to,dist; 13 edge *next; 14 }e[maxm],*head[maxn]; 15 16 int s,t; 17 int cnt=0; 18 int ne=0,time=0; 19 int from[maxm],to[maxm]; 20 int dfn[maxn],low[maxn],belong[maxn],sta[maxn],top=0; 21 int d[maxn],v[maxn],f[maxn],q[maxn]; 22 bool vis[maxn]; 23 24 inline void add_edge(int from,int to) 25 { 26 e[ne].to=to; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void tarjan(int now) 32 { 33 dfn[now]=low[now]=++time; 34 sta[++top]=now; 35 vis[now]=1; 36 for (edge *p=head[now];p;p=p->next) 37 if (!dfn[p->to]) 38 { 39 tarjan(p->to); 40 low[now]=min(low[now],low[p->to]); 41 } 42 else 43 if (vis[p->to]) 44 low[now]=min(low[now],dfn[p->to]); 45 if (dfn[now] == low[now]) 46 { 47 int p; 48 cnt++; 49 do 50 { 51 p=sta[top--]; 52 vis[p]=0; 53 belong[p]=cnt; 54 f[cnt]+=v[p]; 55 } 56 while (p != now); 57 } 58 } 59 60 inline int spfa() 61 { 62 memset(vis,0,sizeof(vis)); 63 int op=0,cls=1; 64 q[1]=s; 65 d[s]=f[s]; 66 vis[s]=1; 67 while (op != cls) 68 { 69 op=op == maxn-1 ? 0 : op+1; 70 int x=q[op]; 71 for (edge *p=head[x];p;p=p->next) 72 if (d[p->to] < d[x]+f[p->to]) 73 { 74 d[p->to]=d[x]+f[p->to]; 75 if (!vis[p->to]) 76 { 77 vis[p->to]=1; 78 if (op != cls) 79 { 80 int now=op == maxn-1 ? 0 : op+1; 81 if (d[p->to] > d[q[now]]) 82 { 83 q[op]=p->to; 84 op=op ? op-1 : maxn-1; 85 } 86 else 87 { 88 cls=cls == maxn-1 ? 0 : cls+1; 89 q[cls]=p->to; 90 } 91 } 92 else 93 { 94 cls=cls == maxn-1 ? 0 : cls+1; 95 q[cls]=p->to; 96 } 97 } 98 } 99 vis[x]=0; 100 } 101 return d[t]; 102 } 103 104 inline void read(int &x) 105 { 106 x=0; 107 char ch; 108 while (ch=getchar(),ch > '9' || ch < '0'); 109 x=ch-'0'; 110 while (ch=getchar(),ch <= '9' && ch >= '0') 111 x=(x<<3)+x+x+ch-'0'; 112 } 113 114 int main() 115 { 116 int n,m; 117 read(n); 118 read(m); 119 for (int i=1;i<=m;i++) 120 { 121 read(from[i]); 122 read(to[i]); 123 add_edge(from[i],to[i]); 124 belong[i]=i; 125 } 126 for (int i=1;i<=n;i++) 127 read(v[i]); 128 for (int i=1;i<=n;i++) 129 if (!dfn[i]) 130 tarjan(i); 131 read(s); 132 s=belong[s]; 133 t=cnt+1; 134 memset(head,0,sizeof(head)); 135 ne=0; 136 for (int i=1;i<=m;i++) 137 if (belong[from[i]] != belong[to[i]]) 138 add_edge(belong[from[i]],belong[to[i]]); 139 int p; 140 read(p); 141 for (int i=1;i<=p;i++) 142 { 143 int x; 144 read(x); 145 add_edge(belong[x],t); 146 } 147 printf("%d\n",spfa()); 148 return 0; 149 }
bzoj1191
正解是匈牙利,我看了一眼数据范围,加上又不会写匈牙利,然后就写了奇慢无比的枚举加边网络流
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 2010 5 #define maxm 100010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int to,flow; 11 edge *part,*next; 12 }e[maxm],*head[maxn]; 13 14 int s=0,t=maxn-1,ne=0; 15 int q[maxn],d[maxn]; 16 17 inline int min(int a,int b) 18 { 19 return a < b ? a : b; 20 } 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 d[p->to]=d[x]+1; 51 q[++cls]=p->to; 52 } 53 } 54 return d[t] != -1; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int main() 84 { 85 int n,m; 86 scanf("%d%d",&n,&m); 87 for (int i=1;i<=m;i++) 88 { 89 int x,y; 90 scanf("%d%d",&x,&y); 91 x++; 92 y++; 93 add_edge(x,i+n,1); 94 if (x != y) 95 add_edge(y,i+n,1); 96 } 97 for (int i=1;i<=n;i++) 98 add_edge(s,i,1); 99 int ans=0; 100 for (int i=n+1;i<=n+m;i++) 101 { 102 add_edge(i,t,1); 103 int now=dinic(); 104 if (now) 105 ans++; 106 else 107 break; 108 } 109 printf("%d\n",ans); 110 return 0; 111 }
bzoj1192
可以竞选bzoj十大水题了。。。不会具体证明,举了几个例子发现没问题之后就写了,然后就A了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 long long bit[50]; 7 8 int main() 9 { 10 long long x; 11 bit[0]=1; 12 for (int i=1;i<=40;i++) 13 bit[i]=bit[i-1]+bit[i-1]; 14 scanf("%lld",&x); 15 printf("%d\n",upper_bound(bit,bit+40,x)-bit); 16 return 0; 17 }
bzoj1196
本来是需要二分最长一级公路的长度的,不知道为什么直接MST也是对的。。。应该是数据太水
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 10010 7 #define maxm 20010 8 9 struct edge 10 { 11 int from,to,d1,d2,flag; 12 }e[maxm]; 13 14 int f[maxn],r[maxn]; 15 16 inline bool cmp1(const edge a,const edge b) 17 { 18 return a.d1 < b.d1; 19 } 20 21 inline bool cmp2(const edge a,const edge b) 22 { 23 return a.d2 < b.d2; 24 } 25 26 int find(int x) 27 { 28 if (f[x] == x) 29 return x; 30 return f[x]=find(f[x]); 31 } 32 33 inline void _union(int x,int y) 34 { 35 if (r[x] <= r[y]) 36 { 37 f[x]=y; 38 r[y]+=r[x]; 39 } 40 else 41 { 42 f[y]=x; 43 r[x]+=r[y]; 44 } 45 } 46 47 int main() 48 { 49 int n,k,m; 50 scanf("%d%d%d",&n,&k,&m); 51 for (int i=1;i<m;i++) 52 scanf("%d%d%d%d",&e[i].from,&e[i].to,&e[i].d1,&e[i].d2); 53 for (int i=1;i<=n;i++) 54 { 55 f[i]=i; 56 r[i]=1; 57 } 58 int cnt=0,ans=0; 59 if (k) 60 { 61 sort(e+1,e+m,cmp1); 62 for (int i=1;i<=m;i++) 63 { 64 int x=find(e[i].from),y=find(e[i].to); 65 if (x == y) 66 continue; 67 _union(x,y); 68 k--; 69 cnt++; 70 e[i].flag=1; 71 ans=max(ans,e[i].d1); 72 if (!k) 73 break; 74 } 75 } 76 sort(e+1,e+m,cmp2); 77 for (int i=1;i<=m;i++) 78 if (!e[i].flag) 79 { 80 int x=find(e[i].from),y=find(e[i].to); 81 if (x == y) 82 continue; 83 _union(x,y); 84 cnt++; 85 ans=max(ans,e[i].d2); 86 if (cnt == n-1) 87 break; 88 } 89 printf("%d\n",ans); 90 return 0; 91 }
bzoj1207
m^2的DP
1 #include <cstdio> 2 3 #define maxn 10010 4 5 int f[maxn]; 6 int x[maxn],y[maxn],t[maxn]; 7 8 inline void read(int &x) 9 { 10 char ch; 11 while (ch=getchar(),ch > '9' || ch < '0'); 12 x=ch-'0'; 13 while (ch=getchar(),ch <= '9' && ch >= '0') 14 x=(x<<3)+x+x+ch-'0'; 15 } 16 17 inline int abs(int x) 18 { 19 return x >= 0 ? x : -x; 20 } 21 22 inline int max(int a,int b) 23 { 24 return a > b ? a : b; 25 } 26 27 int main() 28 { 29 int n,m; 30 read(n); 31 read(m); 32 for (int i=1;i<=m;i++) 33 { 34 read(t[i]); 35 read(x[i]); 36 read(y[i]); 37 } 38 for (int i=2;i<=m;i++) 39 for (int j=1;j<i;j++) 40 if (abs(y[i]-y[j])+abs(x[i]-x[j]) <= t[i]-t[j]) 41 f[i]=max(f[i],f[j]+1); 42 int ans=0; 43 for (int i=1;i<=m;i++) 44 ans=max(ans,f[i]); 45 printf("%d\n",ans+1); 46 return 0; 47 }
bzoj1208
裸的平衡树
1 #include <cstdio> 2 3 const int maxn=80010; 4 const int mod=1000000; 5 const int inf=0x3f3f3f3f; 6 7 int n,flag=-1,ans=0; 8 9 struct Node 10 { 11 int v,size; 12 Node* s[2]; 13 Node() 14 { 15 v=size=0; 16 } 17 }; 18 19 struct sbt 20 { 21 Node t[maxn],null; 22 Node *root; 23 int ne; 24 25 sbt() 26 { 27 ne=0; 28 null.s[0]=null.s[1]=&null; 29 root=&null; 30 } 31 32 inline void _rot(Node* &now,int l) 33 { 34 int r=!l; 35 Node* s=now->s[l]; 36 now->s[l]=s->s[r]; 37 s->s[r]=now; 38 s->size=now->size; 39 now->size=now->s[0]->size+now->s[1]->size+1; 40 now=s; 41 } 42 43 void _maintain(Node* &now,int l) 44 { 45 int r=!l; 46 if (now->s[l]->s[l]->size > now->s[r]->size) 47 _rot(now,l); 48 else 49 { 50 if (now->s[l]->s[r]->size > now->s[r]->size) 51 { 52 _rot(now->s[l],r); 53 _rot(now,l); 54 } 55 else 56 return; 57 } 58 _maintain(now->s[0],0); 59 _maintain(now->s[1],1); 60 _maintain(now,0); 61 _maintain(now,1); 62 } 63 64 void insert(Node* &now,int v) 65 { 66 if (now == &null) 67 { 68 now=&t[ne++]; 69 now->v=v; 70 now->size=1; 71 now->s[0]=now->s[1]=&null; 72 return; 73 } 74 now->size++; 75 if (v < now->v) 76 insert(now->s[0],v); 77 else 78 insert(now->s[1],v); 79 _maintain(now,v >= now->v); 80 } 81 82 inline int pred(int v) 83 { 84 Node* now=root; 85 int ans=-inf; 86 while (1) 87 { 88 if (now == &null) 89 return ans; 90 if (v <= now->v) 91 now=now->s[0]; 92 else 93 { 94 ans=now->v; 95 now=now->s[1]; 96 } 97 } 98 } 99 100 inline int suc(int v) 101 { 102 Node* now=root; 103 int ans=inf; 104 while (1) 105 { 106 if (now == &null) 107 return ans; 108 if (v >= now->v) 109 now=now->s[1]; 110 else 111 { 112 ans=now->v; 113 now=now->s[0]; 114 } 115 } 116 } 117 118 inline bool find(int v) 119 { 120 Node* now=root; 121 while (1) 122 { 123 if (now == &null) 124 return 0; 125 if (now->v == v) 126 return 1; 127 now=now->s[v >= now->v]; 128 } 129 } 130 131 int del(Node* &now,int v) 132 { 133 now->size--; 134 if (now->v == v || (v < now->v && now->s[0] == &null) || (v > now->v && now->s[1] == &null)) 135 { 136 int t=now->v; 137 if (now->s[0] == &null) 138 now=now->s[1]; 139 else 140 { 141 if (now->s[1] == &null) 142 now=now->s[0]; 143 else 144 now->v=del(now->s[1],0); 145 } 146 return t; 147 } 148 else 149 { 150 if (v < now->v) 151 del(now->s[0],v); 152 else 153 del(now->s[1],v); 154 } 155 } 156 }t; 157 158 int main() 159 { 160 scanf("%d",&n); 161 int x,y; 162 for (int i=1;i<=n;i++) 163 { 164 scanf("%d%d",&x,&y); 165 if (flag == -1) 166 { 167 flag=x; 168 t.insert(t.root,y); 169 } 170 else 171 { 172 if (flag == x) 173 t.insert(t.root,y); 174 else 175 { 176 int l,r; 177 if (t.find(y)) 178 t.del(t.root,y); 179 else 180 { 181 l=t.pred(y); 182 r=t.suc(y); 183 if (y-l <= r-y) 184 { 185 ans+=y-l; 186 ans%=mod; 187 t.del(t.root,l); 188 } 189 else 190 { 191 ans+=r-y; 192 ans%=mod; 193 t.del(t.root,r); 194 } 195 } 196 if (t.root->size == 0) 197 flag=-1; 198 } 199 } 200 } 201 printf("%d\n",ans); 202 return 0; 203 }
bzoj1211
prufer编码,不用高精
1 #include <cstdio> 2 3 #define maxn 160 4 5 long long d[maxn]; 6 7 int main() 8 { 9 long long n; 10 scanf("%lld",&n); 11 long long ans=1,sum=0; 12 for (long long i=1;i<=n;i++) 13 { 14 scanf("%lld",&d[i]); 15 if (d[i] >= n) 16 { 17 puts("0"); 18 return 0; 19 } 20 d[i]--; 21 sum+=d[i]; 22 } 23 if (sum != n-2) 24 { 25 puts("0"); 26 return 0; 27 } 28 for (long long i=1;i<=n-2;i++) 29 { 30 ans*=n-2-i+1; 31 for (long long j=1;j<=n;j++) 32 if (d[j] >= i) 33 ans/=i; 34 } 35 printf("%lld\n",ans); 36 return 0; 37 }
bzoj1221
很不错的费用流建模练手题
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 10010 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow,cost; 16 edge *next,*part; 17 }e[maxm],*head[maxn],*prev[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 bool flag[maxn]; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 inline bool spfa() 41 { 42 memset(d,0x3f,sizeof(d)); 43 memset(flag,0,sizeof(flag)); 44 int op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 flag[s]=1; 48 while (op != cls) 49 { 50 op=op == maxn-1 ? 0 : op+1; 51 int x=q[op]; 52 for (edge *p=head[x];p;p=p->next) 53 if (p->flow && d[p->to] > d[x]+p->cost) 54 { 55 d[p->to]=d[x]+p->cost; 56 prev[p->to]=p->part; 57 if (!flag[p->to]) 58 { 59 if (op != cls) 60 { 61 int now=op == maxn-1 ? 0 : op+1; 62 if (d[p->to] < d[q[now]]) 63 { 64 q[op]=p->to; 65 op=op == 0 ? maxn-1 : op-1; 66 } 67 else 68 { 69 cls=cls == maxn-1 ? 0 : cls+1; 70 q[cls]=p->to; 71 } 72 } 73 else 74 { 75 cls=cls == maxn-1 ? 0 : cls+1; 76 q[cls]=p->to; 77 } 78 flag[p->to]=1; 79 } 80 } 81 flag[x]=0; 82 } 83 return d[t] != inf; 84 } 85 86 inline int agument() 87 { 88 int f=inf,ans=0; 89 for (edge *p=prev[t];p;p=prev[p->to]) 90 f=min(f,p->part->flow); 91 for (edge *p=prev[t];p;p=prev[p->to]) 92 { 93 p->flow+=f; 94 p->part->flow-=f; 95 ans+=p->part->cost*f; 96 } 97 return ans; 98 } 99 100 inline int min_cost() 101 { 102 int ans=0; 103 while (spfa()) 104 ans+=agument(); 105 return ans; 106 } 107 108 int main() 109 { 110 int n,a,b,f,fa,fb; 111 scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb); 112 for (int i=1;i<=n;i++) 113 { 114 int x; 115 scanf("%d",&x); 116 add_edge(s,i,inf,f); 117 add_edge(i,t,x,0); 118 add_edge(s,i+n,x,0); 119 if (i+a+1 <= n) 120 add_edge(i+n,i+a+1,inf,fa); 121 if (i+b+1 <= n) 122 add_edge(i+n,i+b+1,inf,fb); 123 if (i < n) 124 add_edge(i+n,i+n+1,inf,0); 125 } 126 printf("%d\n",min_cost()); 127 return 0; 128 }
bzoj1230(已隐藏)
水线段树
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 int sum,lazy; 8 }t[maxn<<2]; 9 10 inline void update(int rt) 11 { 12 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum; 13 } 14 15 inline void pushdown(int l,int r,int rt) 16 { 17 if (!t[rt].lazy) 18 return; 19 int mid=(l+r)>>1; 20 t[rt<<1].lazy^=1; 21 t[rt<<1|1].lazy^=1; 22 t[rt<<1].sum=mid-l+1-t[rt<<1].sum; 23 t[rt<<1|1].sum=r-mid-t[rt<<1|1].sum; 24 t[rt].lazy=0; 25 } 26 27 void insert(int l,int r,int rt,int L,int R) 28 { 29 if (l >= L && r <= R) 30 { 31 t[rt].sum=r-l+1-t[rt].sum; 32 t[rt].lazy^=1; 33 return; 34 } 35 int mid=(l+r)>>1; 36 pushdown(l,r,rt); 37 if (L <= mid) 38 insert(l,mid,rt<<1,L,R); 39 if (R > mid) 40 insert(mid+1,r,rt<<1|1,L,R); 41 update(rt); 42 } 43 44 int query(int l,int r,int rt,int L,int R) 45 { 46 if (l >= L && r <= R) 47 return t[rt].sum; 48 int mid=(l+r)>>1,ans=0; 49 pushdown(l,r,rt); 50 if (L <= mid) 51 ans+=query(l,mid,rt<<1,L,R); 52 if (R > mid) 53 ans+=query(mid+1,r,rt<<1|1,L,R); 54 update(rt); 55 return ans; 56 } 57 58 inline void read(int &x) 59 { 60 char ch; 61 while (ch=getchar(),ch > '9' || ch < '0'); 62 x=ch-'0'; 63 while (ch=getchar(),ch <= '9' && ch >= '0') 64 x=(x<<3)+x+x+ch-'0'; 65 } 66 67 int main() 68 { 69 int n,m; 70 read(n); 71 read(m); 72 while (m--) 73 { 74 int x,y,z; 75 read(x); 76 read(y); 77 read(z); 78 if (!x) 79 insert(1,n,1,y,z); 80 else 81 printf("%d\n",query(1,n,1,y,z)); 82 } 83 return 0; 84 }
bzoj1237
a[i]只会与b[i] b[i-1] b[i-2]配对,证明不会。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 100010 8 #define inf 0x3f3f3f3f3f3f3f3fLL 9 10 long long a[maxn],b[maxn]; 11 12 inline void read(long long &x) 13 { 14 char ch; 15 while (ch=getchar(),ch > '9' || ch < '0'); 16 x=ch-'0'; 17 while (ch=getchar(),ch <= '9' && ch >= '0') 18 x=(x<<3)+x+x+ch-'0'; 19 } 20 21 inline long long cal(long long x,long long y) 22 { 23 if (a[x] == b[y]) 24 return inf; 25 return abs(a[x]-b[y]); 26 } 27 28 long long f[maxn]; 29 30 int main() 31 { 32 long long n; 33 read(n); 34 for (long long i=1;i<=n;i++) 35 { 36 read(a[i]); 37 read(b[i]); 38 } 39 sort(a+1,a+n+1); 40 sort(b+1,b+n+1); 41 memset(f,0x3f,sizeof(f)); 42 f[0]=0; 43 f[1]=cal(1,1); 44 f[2]=min(f[1]+cal(2,2),cal(1,2)+cal(2,1)); 45 for (long long i=3;i<=n;i++) 46 f[i]=min(min(min(min(f[i],f[i-1]+cal(i,i)),f[i-2]+cal(i,i-1)+cal(i-1,i)),f[i-3]+cal(i-2,i-1)+cal(i-1,i)+cal(i,i-2)),f[i-3]+cal(i-2,i)+cal(i-1,i-2)+cal(i,i-1)); 47 printf("%lld\n",f[n]); 48 return 0; 49 }
bzoj1251
终结他一脸啊。。。那么水的splay
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 500010 7 #define inf 0x3f3f3f3f 8 9 struct Node 10 { 11 int v,max,size,add; 12 bool rot; 13 Node *s[2],*par; 14 15 Node() 16 { 17 v=max=size=add=rot=0; 18 } 19 20 inline bool S() 21 { 22 return this == par->s[1]; 23 } 24 }; 25 26 struct splay 27 { 28 Node t[maxn],null; 29 Node *root; 30 int ne; 31 32 splay() 33 { 34 null.s[0]=null.s[1]=null.par=&null; 35 null.max=null.v=-inf; 36 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2; 37 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1; 38 ne=2; 39 root=&t[0]; 40 } 41 42 inline void add(Node* now,int d) 43 { 44 now->max+=d; 45 now->v+=d; 46 now->add+=d; 47 } 48 49 inline void _update(Node* now) 50 { 51 if (now == &null) 52 return; 53 now->size=now->s[0]->size+now->s[1]->size+1; 54 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v); 55 } 56 57 inline void _pushdown(Node* now) 58 { 59 if (now == &null) 60 return; 61 if (now->rot) 62 { 63 swap(now->s[0],now->s[1]); 64 now->s[0]->rot^=1; 65 now->s[1]->rot^=1; 66 now->rot=0; 67 } 68 if (now->add) 69 { 70 int d=now->add; 71 add(now->s[0],d); 72 add(now->s[1],d); 73 now->add=0; 74 null.v=null.max=-inf; 75 } 76 } 77 78 inline void build(int n) 79 { 80 Node* now=root; 81 now->size+=n; 82 now=now->s[1]; 83 now->size+=n; 84 Node* par=now; 85 for (int i=1;i<=n;i++) 86 { 87 now=&t[ne++]; 88 (par->s[0]=now)->par=par; 89 now->s[0]=now->s[1]=&null; 90 now->size=n-i+1; 91 par=now; 92 } 93 } 94 95 inline void _rot(Node* now,int l) 96 { 97 int r=!l; 98 Node* s=now->s[l]; 99 Node* p=now->par; 100 (now->s[l]=s->s[r])->par=now; 101 (s->s[r]=now)->par=s; 102 s->par=p; 103 if (p != &null) 104 p->s[now == p->s[1]]=s; 105 _update(now); 106 _update(s); 107 } 108 109 void relax(Node* now) 110 { 111 if (now->par != &null) 112 relax(now->par); 113 _pushdown(now); 114 } 115 116 inline void _splay(Node* now,Node* goal) 117 { 118 relax(now); 119 while (now->par != goal) 120 { 121 Node* p=now->par; 122 Node* g=p->par; 123 bool dp=now == p->s[1]; 124 bool dg=p == g->s[1]; 125 if (p->par == goal) 126 { 127 _rot(p,dp); 128 break; 129 } 130 if (dp == dg) 131 { 132 _rot(g,dg); 133 _rot(p,dp); 134 } 135 else 136 { 137 _rot(p,dp); 138 _rot(g,dg); 139 } 140 } 141 if (goal == &null) 142 root=now; 143 } 144 145 inline Node* _select(int v) 146 { 147 Node* now=root; 148 while (1) 149 { 150 _pushdown(now); 151 if (now == &null) 152 return now; 153 if (now->s[0]->size+1 == v) 154 return now; 155 if (v <= now->s[0]->size) 156 now=now->s[0]; 157 else 158 { 159 v-=now->s[0]->size+1; 160 now=now->s[1]; 161 } 162 } 163 } 164 165 inline void change(int l,int r,int d) 166 { 167 Node* p=_select(l); 168 Node* q=_select(r+2); 169 _splay(p,&null); 170 _splay(q,root); 171 add(q->s[0],d); 172 _update(q); 173 _update(p); 174 } 175 176 inline void rot(int l,int r) 177 { 178 Node* p=_select(l); 179 Node* q=_select(r+2); 180 _splay(p,&null); 181 _splay(q,root); 182 q->s[0]->rot^=1; 183 } 184 185 inline int query(int l,int r) 186 { 187 Node* p=_select(l); 188 Node* q=_select(r+2); 189 _splay(p,&null); 190 _splay(q,root); 191 return q->s[0]->max; 192 } 193 194 void travel(Node* now) 195 { 196 if (now->s[0] != &null) 197 travel(now->s[0]); 198 printf("%d %d %d %d %d\n",now->v,now->max,now->size,now->rot,now->add); 199 if (now->s[1] != &null) 200 travel(now->s[1]); 201 } 202 }t; 203 204 int main() 205 { 206 int n,m; 207 scanf("%d%d",&n,&m); 208 t.build(n); 209 while (m--) 210 { 211 int x,y,z,w; 212 scanf("%d%d%d",&x,&y,&z); 213 if (x == 1) 214 { 215 scanf("%d",&w); 216 t.change(y,z,w); 217 } 218 if (x == 2) 219 t.rot(y,z); 220 if (x == 3) 221 printf("%d\n",t.query(y,z)); 222 } 223 return 0; 224 }
bzoj1257
前sqrt(n)裸,后面的按照商分类
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 long long n,k; 7 8 int main() 9 { 10 scanf("%lld%lld",&n,&k); 11 long long ans=0; 12 for (long long i=1;i<=n;i++) 13 { 14 long long a=k/i,l=k/(a+1)+1,r=a?k/a:n; 15 if (r >= n) 16 r=n; 17 ans+=k*(r-l+1)-a*(l+r)*(r-l+1)/2; 18 i=r; 19 } 20 printf("%lld\n",ans); 21 return 0; 22 }
bzoj1263
直观感受是尽量化成3,然后用2补齐,然后加上高精即可
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 struct wkint 7 { 8 int z[10000],l; 9 bool zf; 10 int maxl(int a,int b) 11 { 12 if (a>b) return(a); 13 else return(b); 14 } 15 bool operator==(const wkint &a) 16 { 17 if (zf ^ a.zf) return(false); 18 if (l!=a.l) return(false); 19 int b; 20 for (b=l;b>=1;b--) 21 if (z[b]!=a.z[b]) return(false); 22 return(true); 23 } 24 bool operator>(const wkint &a) 25 { 26 if (zf ^ a.zf) 27 { 28 if (zf==true) return(true); 29 else return(false); 30 } 31 if (l>a.l) return(zf); 32 if (l<a.l) return(!zf); 33 int b; 34 for (b=l;b>=1;b--) 35 if (z[b]!=a.z[b]) 36 { 37 if (z[b]>a.z[b]) return(zf); 38 else return(!zf); 39 } 40 return(false); 41 } 42 bool operator>=(const wkint &a) 43 { 44 wkint b; 45 b=0; 46 for (int c=0;c<=l;c++) 47 b.z[c]=z[c]; 48 b.l=l; 49 b.zf=zf; 50 if ((b>a) || (b==a)) return(true); 51 else return(false); 52 } 53 bool operator<(const wkint &a) 54 { 55 wkint b; 56 b=0; 57 for (int c=0;c<=l;c++) 58 b.z[c]=z[c]; 59 b.l=l; 60 b.zf=zf; 61 return(!(b>=a)); 62 } 63 bool operator<=(const wkint &a) 64 { 65 wkint b; 66 b=0; 67 for (int c=0;c<=l;c++) 68 b.z[c]=z[c]; 69 b.l=l; 70 b.zf=zf; 71 return(!(b>a)); 72 } 73 bool operator!=(const wkint &a) 74 { 75 wkint b; 76 b=0; 77 for (int c=0;c<=l;c++) 78 b.z[c]=z[c]; 79 b.l=l; 80 b.zf=zf; 81 return(!(b==a)); 82 } 83 int operator=(const int &a) 84 { 85 memset(z,0,sizeof(z)); 86 l=0; 87 int b=a; 88 if (b<0) 89 { 90 zf=false; 91 b=-b; 92 } 93 else zf=true; 94 do 95 { 96 l++; 97 z[l]=b % 10; 98 b=b / 10; 99 }while(b!=0); 100 return(0); 101 } 102 wkint operator+(const wkint &a) 103 { 104 wkint ans; 105 memset(ans.z,0,sizeof(ans.z)); 106 if (zf ^ a.zf) 107 { 108 int b; 109 wkint c; 110 c.zf=zf; 111 for (b=0;b<=l;b++) 112 c.z[b]=z[b]; 113 c.l=l; 114 if (zf==true) 115 { 116 wkint d; 117 for (b=0;b<=a.l;b++) 118 d.z[b]=a.z[b]; 119 d.l=a.l; 120 d.zf=true; 121 ans=c-d; 122 return(ans); 123 } 124 else 125 { 126 c.zf=true; 127 wkint d=a; 128 ans=d-c; 129 return(ans); 130 } 131 } 132 int ll=maxl(l,a.l); 133 ans.l=ll; 134 int b; 135 for (b=1;b<=ll;b++) 136 { 137 ans.z[b]=ans.z[b]+z[b]+a.z[b]; 138 ans.z[b+1]=ans.z[b] / 10; 139 ans.z[b]=ans.z[b] % 10; 140 } 141 for (ans.l=ll+2;ans.l>=1;ans.l--) 142 if (ans.z[ans.l]!=0) break; 143 ans.zf=zf; 144 return(ans); 145 } 146 wkint operator-(const wkint &a) 147 { 148 wkint ans; 149 memset(ans.z,0,sizeof(0)); 150 if (zf ^ a.zf) 151 { 152 int b; 153 wkint c; 154 for (b=1;b<=l;b++) 155 c.z[b]=z[b]; 156 c.l=l; 157 c.zf=zf; 158 if (zf==true) 159 { 160 wkint d; 161 for (b=1;b<=a.l;b++) 162 d.z[b]=a.z[b]; 163 d.l=a.l; 164 d.zf=true; 165 ans=c+d; 166 return(ans); 167 } 168 else 169 { 170 c.zf=true; 171 ans=c+a; 172 ans.zf=false; 173 return(ans); 174 } 175 } 176 int b; 177 wkint c; 178 for (b=1;b<=l;b++) 179 c.z[b]=z[b]; 180 c.l=l; 181 c.zf=zf; 182 wkint e=a; 183 if (c>=a) ans.zf=true; 184 else 185 { 186 wkint d; 187 d=e; 188 e=c; 189 c=d; 190 ans.zf=false; 191 } 192 int ll=maxl(c.l,e.l); 193 for (b=1;b<=ll;b++) 194 ans.z[b]=c.z[b]-e.z[b]; 195 for (b=1;b<=ll;b++) 196 if (ans.z[b]<0) 197 { 198 ans.z[b]=ans.z[b]+10; 199 ans.z[b+1]--; 200 } 201 for (b=ll;b>=1;b--) 202 if (ans.z[b]!=0) break; 203 if (b==0) b=1; 204 ans.l=b; 205 return(ans); 206 } 207 wkint operator*(const wkint &a) 208 { 209 wkint ans; 210 memset(ans.z,0,sizeof(ans.z)); 211 ans.zf=!(zf ^ a.zf); 212 int b,c; 213 for (b=1;b<=l;b++) 214 for (c=1;c<=a.l;c++) 215 ans.z[b+c-1]=ans.z[b+c-1]+z[b]*a.z[c]; 216 c=0; 217 for (b=1;b<=l+a.l;b++) 218 { 219 ans.z[b]=ans.z[b]+c; 220 c=ans.z[b] / 10; 221 ans.z[b]=ans.z[b] % 10; 222 } 223 while (c!=0) 224 { 225 b++; 226 ans.z[b]=c % 10; 227 c=c /10; 228 } 229 for (c=b;c>=1;c--) 230 if (ans.z[c]!=0) break; 231 if (c==0) c=1; 232 ans.l=c; 233 return(ans); 234 } 235 int print() 236 { 237 int a; 238 if (zf==false) printf("-"); 239 for (a=l;a>=max(1,l-99);a--) 240 printf("%d",z[a]); 241 printf("\n"); 242 return(0); 243 } 244 int printl() 245 { 246 if (zf==true) printf("%d\n",l); 247 else printf("%d\n",l+1); 248 return(0); 249 } 250 }now; 251 252 int main() 253 { 254 int n; 255 wkint ans; 256 ans=1; 257 scanf("%d",&n); 258 if (n%3 == 1) 259 { 260 ans=4; 261 n-=4; 262 } 263 if (n%3 == 2) 264 { 265 ans=2; 266 n-=2; 267 } 268 n/=3; 269 wkint wk; 270 wk=3; 271 for (;n;n>>=1) 272 { 273 if (n&1) 274 ans=ans*wk; 275 wk=wk*wk; 276 } 277 ans.printl(); 278 ans.print(); 279 return 0; 280 }
bzoj1266
最短路图上的最小割
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 510 8 #define maxm 500010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,flow; 14 edge *next,*part; 15 }e[maxm],*head[maxn]; 16 17 int ne=0; 18 int s,t; 19 int q[maxn],d[maxn]; 20 int from[maxm],to[maxm],dist[maxm],flow[maxm]; 21 bool flag[maxn]; 22 23 inline void add_edge0(int from,int to,int flow) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void add(int from,int to,int flow) 32 { 33 e[ne].to=to; 34 e[ne].flow=flow; 35 e[ne].next=head[from]; 36 head[from]=&e[ne++]; 37 } 38 39 inline void add_edge(int from,int to,int flow) 40 { 41 e[ne].part=&e[ne+1]; 42 e[ne+1].part=&e[ne]; 43 add(from,to,flow); 44 add(to,from,0); 45 } 46 47 inline void spfa() 48 { 49 memset(d,0x3f,sizeof(d)); 50 memset(flag,0,sizeof(flag)); 51 int op=0,cls=1; 52 q[1]=s; 53 d[s]=0; 54 flag[s]=1; 55 while (op != cls) 56 { 57 op=op == maxn-1 ? 0 : op+1; 58 int x=q[op]; 59 for (edge *p=head[x];p;p=p->next) 60 if (d[x]+p->flow < d[p->to]) 61 { 62 d[p->to]=d[x]+p->flow; 63 if (!flag[p->to]) 64 { 65 flag[p->to]=1; 66 if (op != cls) 67 { 68 int now=op == maxn-1 ? 0 : op+1; 69 if (d[p->to] < d[q[now]]) 70 { 71 q[op]=p->to; 72 op=op ? op-1 : maxn-1; 73 } 74 else 75 { 76 cls=cls == maxn-1 ? 0 : cls+1; 77 q[cls]=p->to; 78 } 79 } 80 else 81 { 82 cls=cls == maxn-1 ? 0 : cls+1; 83 q[cls]=p->to; 84 } 85 } 86 } 87 flag[x]=0; 88 } 89 } 90 91 inline bool bfs() 92 { 93 memset(d,-1,sizeof(d)); 94 int op=0,cls=1; 95 q[1]=s; 96 d[s]=0; 97 while (op != cls) 98 { 99 int x=q[++op]; 100 for (edge *p=head[x];p;p=p->next) 101 if (p->flow && d[p->to] == -1) 102 { 103 d[p->to]=d[x]+1; 104 q[++cls]=p->to; 105 } 106 } 107 return ~d[t]; 108 } 109 110 inline int dfs(int now,int now_flow) 111 { 112 if (now == t) 113 return now_flow; 114 int out=now_flow; 115 for (edge *p=head[now];p;p=p->next) 116 if (p->flow && d[p->to] == d[now]+1 && out) 117 { 118 int f=dfs(p->to,min(p->flow,out)); 119 p->flow-=f; 120 p->part->flow+=f; 121 out-=f; 122 } 123 if (out == now_flow) 124 d[now]=-1; 125 return now_flow-out; 126 } 127 128 inline int dinic() 129 { 130 int ans=0; 131 while (bfs()) 132 ans+=dfs(s,inf); 133 return ans; 134 } 135 136 int main() 137 { 138 int n,m; 139 scanf("%d%d",&n,&m); 140 s=1; 141 t=n; 142 for (int i=1;i<=m;i++) 143 { 144 scanf("%d%d%d%d",&from[i],&to[i],&dist[i],&flow[i]); 145 add_edge0(from[i],to[i],dist[i]); 146 add_edge0(to[i],from[i],dist[i]); 147 } 148 spfa(); 149 printf("%d\n",d[t]); 150 memset(head,0,sizeof(head)); 151 ne=0; 152 for (int i=1;i<=m;i++) 153 { 154 if (d[from[i]]+dist[i] == d[to[i]]) 155 add_edge(from[i],to[i],flow[i]); 156 if (d[to[i]]+dist[i] == d[from[i]]) 157 add_edge(to[i],from[i],flow[i]); 158 } 159 printf("%d\n",dinic()); 160 return 0; 161 }
bzoj1269
人生中第一道splay。。。注意使用保护节点(这句话是说给不会splay的同学的)
1 #include <cstdio> 2 3 const int maxn=1024*1024*3; 4 5 int n; 6 char s[maxn],st[10]; 7 8 struct Node 9 { 10 int size; 11 bool rot; 12 char ch; 13 Node *par,*s[2]; 14 Node() 15 { 16 size=0; 17 rot=false; 18 } 19 }; 20 21 struct splay 22 { 23 Node t[maxn],null; 24 Node* root; 25 int size; 26 splay() 27 { 28 root=&t[1]; 29 size=2; 30 null.par=null.s[0]=null.s[1]=&null; 31 t[1].s[0]=&null;t[1].s[1]=&t[2];t[1].par=&null;t[1].size=2; 32 t[2].s[0]=&null;t[2].s[1]=&null;t[2].par=&t[1];t[2].size=1; 33 } 34 35 void _update(Node* now) 36 { 37 now->size=now->s[0]->size+now->s[1]->size+1; 38 } 39 40 void _pushdown(Node* now) 41 { 42 if (now != &null && now->rot) 43 { 44 now->s[0]->rot^=1; 45 now->s[1]->rot^=1; 46 Node* temp=now->s[0]->s[0]; 47 now->s[0]->s[0]=now->s[0]->s[1]; 48 now->s[0]->s[1]=temp; 49 temp=now->s[1]->s[0]; 50 now->s[1]->s[0]=now->s[1]->s[1]; 51 now->s[1]->s[1]=temp; 52 now->rot=false; 53 } 54 } 55 56 void _rot(Node* now,int l) 57 { 58 int r=!l; 59 Node* s=now->s[l]; 60 Node* p=now->par; 61 (now->s[l]=s->s[r])->par=now; 62 (s->s[r]=now)->par=s; 63 s->par=p; 64 if (p != &null) 65 p->s[now == p->s[1]]=s; 66 _update(now); 67 _update(s); 68 } 69 70 void _splay(Node* now,Node* goal) 71 { 72 while (now->par != goal) 73 { 74 Node* p=now->par; 75 Node* g=p->par; 76 _pushdown(g); 77 _pushdown(p); 78 bool dp=now == p->s[1]; 79 bool dg=p == g->s[1]; 80 if (g == goal) 81 { 82 _rot(p,dp); 83 } 84 else 85 { 86 if (dp == dg) 87 { 88 _rot(g,dg); 89 _rot(p,dp); 90 } 91 else 92 { 93 _rot(p,dp); 94 _rot(g,dg); 95 } 96 } 97 } 98 if (goal == &null) 99 root=now; 100 } 101 102 Node* _select(int v) 103 { 104 Node* now=root; 105 while (v) 106 { 107 _pushdown(now); 108 if (now->s[0]->size+1 == v) 109 return now; 110 else 111 { 112 if (v <= now->s[0]->size) 113 now=now->s[0]; 114 else 115 { 116 v-=now->s[0]->size+1; 117 now=now->s[1]; 118 } 119 } 120 } 121 return &null; 122 } 123 124 void insert(int pos,int len) 125 { 126 Node* p=_select(pos); 127 Node* q=_select(pos+1); 128 _splay(p,&null); 129 _splay(q,root); 130 Node* now=root; 131 now->size+=len; 132 now=now->s[1]; 133 now->size+=len; 134 Node* par=now; 135 for (int i=1;i<=len;i++) 136 { 137 scanf("%c",&s[i]); 138 if (s[i] == '\n' || s[i] == '\r') 139 i--; 140 } 141 for (int i=1;i<=len;i++) 142 { 143 size++; 144 now=&t[size]; 145 (par->s[0]=now)->par=par; 146 now->s[0]=now->s[1]=&null; 147 now->size=len-i+1; 148 now->ch=s[len-i+1]; 149 par=now; 150 } 151 _splay(now,&null); 152 } 153 154 void del(int pos,int len) 155 { 156 Node* p=_select(pos); 157 Node* q=_select(pos+len+1); 158 _splay(p,&null); 159 _splay(q,root); 160 root->s[1]->s[0]=&null; 161 _update(root->s[1]); 162 _update(root); 163 } 164 165 void rot(int pos,int len) 166 { 167 Node* p=_select(pos); 168 Node* q=_select(pos+len+1); 169 _splay(p,&null); 170 _splay(q,root); 171 Node* now=root->s[1]->s[0]; 172 now->rot^=1; 173 Node* temp=now->s[0]; 174 now->s[0]=now->s[1]; 175 now->s[1]=temp; 176 } 177 178 void print(int pos) 179 { 180 Node* now=_select(pos); 181 _splay(now,&null); 182 printf("%c",now->ch); 183 printf("\n"); 184 } 185 }t; 186 187 int main() 188 { 189 int pos=1,len; 190 scanf("%d",&n); 191 while (n--) 192 { 193 scanf("%s",st); 194 if (st[0] == 'M') 195 { 196 scanf("%d",&pos); 197 pos++; 198 } 199 if (st[0] == 'I') 200 { 201 scanf("%d",&len); 202 char c='~'; 203 while (c != '\n' && c != '\r') 204 c=getchar(); 205 t.insert(pos,len); 206 } 207 if (st[0] == 'D') 208 { 209 scanf("%d",&len); 210 t.del(pos,len); 211 } 212 if (st[0] == 'R') 213 { 214 scanf("%d",&len); 215 t.rot(pos,len); 216 } 217 if (st[0] == 'G') 218 { 219 t.print(pos+1); 220 } 221 if (st[0] == 'P') 222 pos--; 223 if (st[0] == 'N') 224 pos++; 225 } 226 return 0; 227 }
bzoj1272
组合数求模终极版的弱化版+一点点容斥,必须要预处理阶乘才能过(相比之下2142是多么的良心。。。以近乎裸的方式过了)详细做法可以百度组合数求模看AC大神的日志
1 #include <cstdio> 2 3 int n,t,m,p; 4 int a[20],mul[100010],ans=0; 5 bool use[20]; 6 7 inline void inc(int &a,int b) 8 { 9 a+=b; 10 while (a >= p) 11 a-=p; 12 } 13 14 inline void dec(int &a,int b) 15 { 16 a-=b; 17 while (a < 0) 18 a+=p; 19 } 20 21 inline int pow(int a,int b) 22 { 23 int ans=1; 24 while (b) 25 { 26 if (b&1) 27 ans=(long long)ans*a%p; 28 a=(long long)a*a%p; 29 b>>=1; 30 } 31 return ans; 32 } 33 34 inline int get(int v) 35 { 36 int ans=0; 37 while (v) 38 { 39 ans+=v/p; 40 v/=p; 41 } 42 return ans; 43 } 44 45 inline int cal(int n) 46 { 47 if (n < p) 48 return mul[n]; 49 else 50 return (long long)pow(mul[p],n/p)*cal(n/p)%p*mul[n%p]%p; 51 } 52 53 inline int calc(int a,int b) 54 { 55 int now=get(a)-get(b)-get(a-b); 56 if (now) 57 return 0; 58 return (long long)cal(a)*pow(cal(b),p-2)%p*pow(cal(a-b),p-2)%p; 59 } 60 61 inline void solve() 62 { 63 int now=m,ban=0; 64 for (int i=1;i<=t;i++) 65 if (use[i]) 66 { 67 ban++; 68 now-=a[i]+1; 69 } 70 if (now < 0) 71 return; 72 if (ban%2 == 0) 73 inc(ans,calc(now+n,n)); 74 else 75 dec(ans,calc(now+n,n)); 76 } 77 78 inline void dfs(int now) 79 { 80 if (now > t) 81 solve(); 82 else 83 { 84 use[now]=0; 85 dfs(now+1); 86 use[now]=1; 87 dfs(now+1); 88 } 89 } 90 91 int main() 92 { 93 scanf("%d%d%d%d",&n,&t,&m,&p); 94 for (int i=1;i<=t;i++) 95 scanf("%d",&a[i]); 96 mul[0]=1; 97 for (int i=1;i<p;i++) 98 mul[i]=(long long)mul[i-1]*i%p; 99 mul[p]=mul[p-1]; 100 dfs(1); 101 printf("%d\n",ans); 102 }
bzoj1273
在序列只有整体加上一个数的情况下,对于每一个2^i,答案存在循环节,于是暴力预处理之后O(1)回答询问即可
1 #include <cstdio> 2 3 #define maxn 100010 4 5 int a[16][maxn],ans[16][maxn]; 6 int bit[20]; 7 8 inline void read(int &x) 9 { 10 char ch; 11 while (ch=getchar(),ch > '9' || ch < '0'); 12 x=ch-'0'; 13 while (ch=getchar(),ch <= '9' && ch >= '0') 14 x=(x<<3)+x+x+ch-'0'; 15 } 16 17 int main() 18 { 19 int n,_; 20 read(n); 21 read(_); 22 bit[0]=1; 23 for (int i=1;i<=18;i++) 24 bit[i]=bit[i-1]+bit[i-1]; 25 for (int i=1;i<=n;i++) 26 { 27 int x; 28 read(x); 29 for (int j=0;j<16;j++) 30 a[j][x%bit[j+1]]++; 31 } 32 for (int i=0;i<16;i++) 33 for (int j=bit[i];j<bit[i+1];j++) 34 ans[i][0]+=a[i][j]; 35 for (int i=0;i<16;i++) 36 for (int j=1;j<bit[i+1];j++) 37 { 38 ans[i][j]=ans[i][j-1]; 39 ans[i][j]+=a[i][(bit[i]-j+bit[i+1])%bit[i+1]]; 40 ans[i][j]-=a[i][bit[i+1]-j]; 41 } 42 int add=0; 43 long long now=0; 44 while (_--) 45 { 46 char s[2]; 47 int x; 48 scanf("%s",s); 49 read(x); 50 if (s[0] == 'A') 51 (add+=x)%=65536; 52 else 53 if (x < 16) 54 now+=ans[x][add%bit[x+1]]; 55 } 56 printf("%lld\n",now); 57 return 0; 58 }
bzoj1296
水水的DP,当时想各种优化状态,结果人弱写挂没办法。。。然后就暴力DP了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 55 7 #define maxt 2510 8 9 int f[maxn][maxn][maxt][2]; 10 bool map[maxn][maxn]; 11 12 int main() 13 { 14 int n,m,t; 15 scanf("%d%d%d",&n,&m,&t); 16 for (int i=1;i<=n;i++) 17 for (int j=1;j<=m;j++) 18 { 19 char ch; 20 while (ch=getchar(),ch != '1' && ch != '0'); 21 map[i][j]=ch-'0'; 22 } 23 for (int i=1;i<=n;i++) 24 { 25 bool now=map[i][1]; 26 for (int j=min((i-1)*m+1,t);j;j--) 27 { 28 f[i][1][j][now]=max(f[i-1][m][j-1][0],f[i-1][m][j-1][1])+1; 29 f[i][1][j][!now]=f[i][1][j][now]-1; 30 } 31 for (int j=2;j<=m;j++) 32 { 33 now=map[i][j]; 34 for (int k=min((i-1)*m+j,t);k;k--) 35 { 36 f[i][j][k][now]=max(f[i][j-1][k][now]+1,f[i][j-1][k-1][!now]+1); 37 f[i][j][k][!now]=f[i][j-1][k][!now]; 38 } 39 } 40 } 41 int ans=0; 42 for (int i=1;i<=t;i++) 43 ans=max(max(f[n][m][i][0],f[n][m][i][1]),ans); 44 printf("%d\n",ans); 45 return 0; 46 }
bzoj1303
把所有比b大的赋为1,比b小的赋为-1,找到b所在的位置,然后向两边拓展,处理出前(后)缀和为x的个数,最后合并。。。怀念pascal可以负数下标
1 #include <cstdio> 2 3 #define maxn 100010 4 #define inf 0x3f3f3f3f 5 6 int a[maxn],sum[maxn<<1]; 7 8 inline void read(int &x) 9 { 10 char ch; 11 while (ch=getchar(),ch > '9' || ch < '0'); 12 x=ch-'0'; 13 while (ch=getchar(),ch <= '9' && ch >= '0') 14 x=(x<<3)+x+x+ch-'0'; 15 } 16 17 int main() 18 { 19 int n,b; 20 read(n); 21 read(b); 22 int now=0; 23 for (int i=1;i<=n;i++) 24 { 25 int x; 26 scanf("%d",&x); 27 if (x < b) 28 a[i]=-1; 29 else 30 if (x > b) 31 a[i]=1; 32 else 33 { 34 now=i; 35 a[i]=0; 36 } 37 } 38 sum[n]++; 39 for (int i=now+1;i<=n;i++) 40 { 41 a[i]+=a[i-1]; 42 sum[a[i]+n]++; 43 } 44 int ans=0,num=0; 45 for (int i=now;i;i--) 46 { 47 num+=a[i]; 48 ans+=sum[-num+n]; 49 } 50 printf("%d\n",ans); 51 return 0; 52 }
bzoj1305
贪心即可(不会证明,可能是错的)
1 #include <cstdio> 2 3 #define maxn 60 4 #define inf 0x3f3f3f3f 5 6 int a[maxn]; 7 8 inline int min(int a,int b) 9 { 10 return a < b ? a : b; 11 } 12 13 int main() 14 { 15 int n,k; 16 scanf("%d%d\n",&n,&k); 17 int ming=inf,minb=inf; 18 for (int i=1;i<=n;i++) 19 { 20 char ch; 21 int now=0; 22 for (int j=1;j<=n;j++) 23 { 24 ch=getchar(); 25 if (ch == 'Y') 26 { 27 now++; 28 a[j]++; 29 } 30 } 31 while (ch=getchar(),ch != '\n' && ch != '\r'); 32 minb=min(minb,now); 33 } 34 for (int i=1;i<=n;i++) 35 ming=min(ming,a[i]); 36 printf("%d\n",min(n,min(ming,minb)+k)); 37 return 0; 38 }
bzoj1406
n|(x^2-1)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1010 7 8 int ans[maxn]; 9 10 int main() 11 { 12 int n,cnt=0; 13 scanf("%d",&n); 14 for (int i=1;i*i <= n;i++) 15 if (n%i == 0) 16 { 17 int x=n/i; 18 for (int j=1;j<=n;j+=x) 19 if ((j+1)%i == 0) 20 ans[++cnt]=j; 21 for (int j=x-1;j<=n;j+=x) 22 if ((j-1)%i == 0) 23 ans[++cnt]=j; 24 } 25 sort(ans+1,ans+cnt+1); 26 cnt=unique(ans+1,ans+cnt+1)-ans-1; 27 if (!cnt) 28 puts("None"); 29 else 30 for (int i=1;i<=cnt;i++) 31 printf("%d\n",ans[i]); 32 return 0; 33 }
bzoj1412
典型的最小割模型
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 20010 8 #define maxm 1000010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 const int fx[]={0,1,0,-1}; 14 const int fy[]={-1,0,1,0}; 15 16 struct edge 17 { 18 int to,flow; 19 edge *next,*part; 20 }e[maxm],*head[maxn]; 21 22 int ne=0; 23 int q[maxn],d[maxn]; 24 25 inline void add(int from,int to,int flow) 26 { 27 e[ne].to=to; 28 e[ne].flow=flow; 29 e[ne].next=head[from]; 30 head[from]=&e[ne++]; 31 } 32 33 inline void add_edge(int from,int to,int flow) 34 { 35 e[ne].part=&e[ne+1]; 36 e[ne+1].part=&e[ne]; 37 add(from,to,flow); 38 add(to,from,0); 39 } 40 41 inline bool bfs() 42 { 43 memset(d,-1,sizeof(d)); 44 int op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 while (op !=cls) 48 { 49 int x=q[++op]; 50 for (edge *p=head[x];p;p=p->next) 51 if (p->flow && d[p->to] == -1) 52 { 53 d[p->to]=d[x]+1; 54 q[++cls]=p->to; 55 } 56 } 57 return ~d[t]; 58 } 59 60 inline int dfs(int now,int now_flow) 61 { 62 if (now == t) 63 return now_flow; 64 int out=now_flow; 65 for (edge *p=head[now];p;p=p->next) 66 if (p->flow && d[p->to] == d[now]+1 && out) 67 { 68 int f=dfs(p->to,min(p->flow,out)); 69 p->flow-=f; 70 p->part->flow+=f; 71 out-=f; 72 } 73 if (out == now_flow) 74 d[now]=-1; 75 return now_flow-out; 76 } 77 78 inline int dinic() 79 { 80 int ans=0; 81 while (bfs()) 82 ans+=dfs(s,inf); 83 return ans; 84 } 85 86 int map[110][110],pos[110][110]; 87 88 int main() 89 { 90 int n,m; 91 scanf("%d%d",&n,&m); 92 for (int i=1;i<=n;i++) 93 for (int j=1;j<=m;j++) 94 { 95 scanf("%d",&map[i][j]); 96 pos[i][j]=(i-1)*m+j; 97 } 98 for (int i=1;i<=n;i++) 99 for (int j=1;j<=m;j++) 100 { 101 if (map[i][j] == 1) 102 add_edge(s,pos[i][j],inf); 103 if (map[i][j] == 2) 104 add_edge(pos[i][j],t,inf); 105 for (int k=0;k<4;k++) 106 { 107 int x=i+fx[k],y=j+fy[k]; 108 if (x > 0 && x <= n && y > 0 && y <= m) 109 { 110 if (map[i][j] == 1 && map[x][y] == 0) 111 add_edge(pos[i][j],pos[x][y],1); 112 if (map[i][j] == 0 && map[x][y] == 2) 113 add_edge(pos[i][j],pos[x][y],1); 114 if (map[i][j] == 1 && map[x][y] == 2) 115 add_edge(pos[i][j],pos[x][y],1); 116 if (map[i][j] == 0 && map[x][y] == 0) 117 add_edge(pos[i][j],pos[x][y],1); 118 } 119 } 120 } 121 printf("%d\n",dinic()); 122 return 0; 123 }
bzoj1433
水水的二分图。。。人弱只能写dinic
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 510 8 #define maxm 1000010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 d[p->to]=d[x]+1; 51 q[++cls]=p->to; 52 } 53 } 54 return ~d[t]; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int a[maxn]; 84 85 int main() 86 { 87 int _; 88 scanf("%d",&_); 89 while (_--) 90 { 91 memset(head,0,sizeof(head)); 92 ne=0; 93 int n; 94 int sum=0; 95 scanf("%d",&n); 96 for (int i=1;i<=n;i++) 97 { 98 scanf("%d",&a[i]); 99 if (a[i]) 100 add_edge(i+n,t,1); 101 } 102 for (int i=1;i<=n;i++) 103 { 104 int x; 105 scanf("%d",&x); 106 if (!a[i]) 107 { 108 add_edge(s,i,1); 109 sum++; 110 } 111 else 112 if (!x) 113 { 114 add_edge(s,i,1); 115 add_edge(i,i+n,1); 116 sum++; 117 } 118 } 119 for (int i=1;i<=n;i++) 120 for (int j=1;j<=n;j++) 121 { 122 int x; 123 scanf("%d",&x); 124 if (x) 125 add_edge(i,j+n,1); 126 } 127 if (dinic() == sum) 128 puts("^_^"); 129 else 130 puts("T_T"); 131 } 132 return 0; 133 }
bzoj1452
观察数据范围后二维树状数组
1 #include <cstdio> 2 3 #define maxn 310 4 #define maxc 110 5 6 int n,m; 7 int col[maxn][maxn]; 8 int bit[maxc][maxn][maxn]; 9 10 inline void bit_update(int c,int x,int y,int val) 11 { 12 for (int i=x;i<=n;i+=i&-i) 13 for (int j=y;j<=m;j+=j&-j) 14 bit[c][i][j]+=val; 15 } 16 17 inline int query(int c,int x,int y) 18 { 19 int ans=0; 20 for (int i=x;i;i-=i&-i) 21 for (int j=y;j;j-=j&-j) 22 ans+=bit[c][i][j]; 23 return ans; 24 } 25 26 int main() 27 { 28 scanf("%d%d",&n,&m); 29 for (int i=1;i<=n;i++) 30 for (int j=1;j<=m;j++) 31 { 32 scanf("%d",&col[i][j]); 33 bit_update(col[i][j],i,j,1); 34 } 35 int _; 36 scanf("%d",&_); 37 while (_--) 38 { 39 int now; 40 scanf("%d",&now); 41 if (now == 1) 42 { 43 int x,y,c; 44 scanf("%d%d%d",&x,&y,&c); 45 bit_update(col[x][y],x,y,-1); 46 col[x][y]=c; 47 bit_update(col[x][y],x,y,1); 48 } 49 else 50 { 51 int x1,x2,y1,y2,c; 52 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c); 53 printf("%d\n",query(c,x2,y2)-query(c,x1-1,y2)-query(c,x2,y1-1)+query(c,x1-1,y1-1)); 54 } 55 } 56 return 0; 57 }
bzoj1485
卡特兰数
1 #include <cstdio> 2 3 #define maxn 2000010 4 5 long long cnt=0; 6 long long p[maxn]; 7 long long mod; 8 bool prime[maxn]; 9 10 inline void get_prime(long long n) 11 { 12 for (long long i=2;i<=n;i++) 13 { 14 if (!prime[i]) 15 p[++cnt]=i; 16 for (long long j=1;j<=cnt && p[j]*i <= n;j++) 17 { 18 prime[i*p[j]]=1; 19 if (i%p[j] == 0) 20 break; 21 } 22 } 23 } 24 25 inline long long pow(long long a,long long b) 26 { 27 long long ans=1,wk=a; 28 for (;b;b>>=1) 29 { 30 if (b&1) 31 (ans*=wk)%=mod; 32 (wk*=wk)%=mod; 33 } 34 return ans; 35 } 36 37 int main() 38 { 39 long long n; 40 scanf("%lld%lld",&n,&mod); 41 get_prime(n*2); 42 long long ans=1; 43 for (long long i=1;i<=cnt;i++) 44 { 45 long long now=0; 46 for (long long j=p[i];j<=2*n;j*=p[i]) 47 now+=(2*n)/j-2*(n/j); 48 if ((n+1)%p[i] == 0) 49 for (long long j=n+1;j%p[i] == 0;j/=p[i]) 50 now--; 51 (ans*=pow(p[i],now))%=mod; 52 } 53 printf("%lld\n",ans); 54 return 0; 55 }
bzoj1486
二分+spfa找负环
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 3010 8 #define maxm 10010 9 #define inf 1e+9 10 11 struct edge 12 { 13 int to; 14 double dist; 15 edge *next; 16 }e[maxm],*head[maxn]; 17 18 int n,m; 19 int ne=0; 20 int q[maxn]; 21 double d[maxn]; 22 int from[maxm],to[maxm]; 23 double dist[maxm]; 24 int now[maxn]; 25 bool flag[maxn]; 26 27 inline void add_edge(int from,int to,double dist) 28 { 29 e[ne].to=to; 30 e[ne].dist=dist; 31 e[ne].next=head[from]; 32 head[from]=&e[ne++]; 33 } 34 35 inline bool spfa() 36 { 37 memset(now,0,sizeof(now)); 38 memset(flag,0,sizeof(flag)); 39 for (int i=1;i<=n;i++) 40 d[i]=inf; 41 d[1]=0; 42 int op=0,cls=1; 43 q[1]=1; 44 now[1]=1; 45 flag[1]=1; 46 while (op != cls) 47 { 48 op++; 49 if (op == maxn) 50 op=0; 51 int x=q[op]; 52 flag[x]=0; 53 for (edge *p=head[x];p;p=p->next) 54 if (d[p->to] > d[x]+p->dist) 55 { 56 d[p->to]=d[x]+p->dist; 57 if (!flag[p->to]) 58 { 59 now[p->to]++; 60 if (now[p->to] > 15) 61 return 1; 62 cls++; 63 if (cls == maxn) 64 cls=0; 65 q[cls]=p->to; 66 flag[p->to]=1; 67 } 68 } 69 } 70 return 0; 71 } 72 73 int main() 74 { 75 scanf("%d%d",&n,&m); 76 for (int i=1;i<=m;i++) 77 scanf("%d%d%lf",&from[i],&to[i],&dist[i]); 78 double l=-inf,r=inf,ans=0.0; 79 for (int t=1;t<=60;t++) 80 { 81 double mid=(l+r)/2; 82 ne=0; 83 memset(head,0x0,sizeof(head)); 84 for (int i=1;i<=m;i++) 85 add_edge(from[i],to[i],dist[i]-mid); 86 if (spfa()) 87 { 88 ans=mid; 89 r=mid; 90 } 91 else 92 l=mid; 93 } 94 printf("%.8lf\n",ans); 95 return 0; 96 }
bzoj1497
最小割模型
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 100010 8 #define maxm 1000010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 q[++cls]=p->to; 51 d[p->to]=d[x]+1; 52 } 53 } 54 return d[t] != -1; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int main() 84 { 85 int n,m,sum=0; 86 scanf("%d%d",&n,&m); 87 for (int i=1;i<=n;i++) 88 { 89 int x; 90 scanf("%d",&x); 91 add_edge(i+m,t,x); 92 } 93 for (int i=1;i<=m;i++) 94 { 95 int x,y,z; 96 scanf("%d%d%d",&x,&y,&z); 97 sum+=z; 98 add_edge(i,x+m,inf); 99 add_edge(i,y+m,inf); 100 add_edge(s,i,z); 101 } 102 printf("%d\n",sum-dinic()); 103 return 0; 104 }
bzoj1500
神级splay,不过真正想清楚了两个小时足够写完了,也可以用块链
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 500010 7 #define inf 0x3f3f3f3f 8 9 struct Node 10 { 11 int sum,lmax,rmax,max,lazy,size,v; 12 bool rot; 13 Node *s[2],*par; 14 15 inline Node() 16 { 17 lmax=rmax=max=lazy=-inf; 18 v=sum=size=rot=0; 19 } 20 21 inline bool S() 22 { 23 return this == par->s[1]; 24 } 25 }; 26 27 struct splay 28 { 29 Node t[maxn],null; 30 Node *root,*sta[maxn]; 31 int top; 32 33 inline splay() 34 { 35 null.s[0]=null.s[1]=null.par=&null; 36 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2; 37 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1; 38 top=0; 39 for (int i=2;i<maxn;i++) 40 sta[++top]=&t[i]; 41 root=&t[0]; 42 } 43 44 inline Node* new_Node(int v) 45 { 46 Node* now=sta[top--]; 47 now->lmax=now->rmax=now->max=now->v=now->sum=v; 48 now->lazy=-inf; 49 now->rot=0; 50 now->s[0]=now->s[1]=now->par=&null; 51 now->size=1; 52 return now; 53 } 54 55 void erase(Node* now) 56 { 57 if (now->s[0] != &null) 58 erase(now->s[0]); 59 if (now->s[1] != &null) 60 erase(now->s[1]); 61 sta[++top]=now; 62 } 63 64 inline void _pushdown(Node* now) 65 { 66 if (now->rot) 67 { 68 swap(now->s[0],now->s[1]); 69 swap(now->s[0]->lmax,now->s[0]->rmax); 70 swap(now->s[1]->lmax,now->s[1]->rmax); 71 now->s[0]->rot^=1; 72 now->s[1]->rot^=1; 73 now->rot^=1; 74 } 75 if (now->lazy != -inf) 76 { 77 int add=now->lazy; 78 now->s[0]->lazy=now->s[0]->v=add; 79 now->s[0]->sum=add*now->s[0]->size; 80 now->s[0]->lmax=now->s[0]->rmax=now->s[0]->max=max(add,add*now->s[0]->size); 81 now->s[1]->lazy=now->s[1]->v=add; 82 now->s[1]->sum=add*now->s[1]->size; 83 now->s[1]->lmax=now->s[1]->rmax=now->s[1]->max=max(add,add*now->s[1]->size); 84 now->lazy=-inf; 85 null.lmax=null.rmax=null.max=null.lazy=-inf; 86 null.v=null.sum=0; 87 } 88 } 89 90 inline void _update(Node* now) 91 { 92 if (now == &null) 93 return; 94 null.lmax=null.rmax=null.max=-inf; 95 now->lmax=max(now->s[0]->lmax,now->s[0]->sum+now->v+max(now->s[1]->lmax,0)); 96 now->rmax=max(now->s[1]->rmax,now->s[1]->sum+now->v+max(now->s[0]->rmax,0)); 97 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v+max(now->s[0]->rmax,0)+max(now->s[1]->lmax,0)); 98 now->sum=now->s[0]->sum+now->s[1]->sum+now->v; 99 now->size=now->s[0]->size+now->s[1]->size+1; 100 } 101 102 inline void _rot(Node* now) 103 { 104 Node* p=now->par; 105 int l=now->S(),r=!l; 106 (p->s[l]=now->s[r])->par=p; 107 now->par=p->par; 108 if (p->par != &null) 109 p->par->s[p->S()]=now; 110 (now->s[r]=p)->par=now; 111 _update(p); 112 _update(now); 113 } 114 115 void _relax(Node* now) 116 { 117 if (now->par != &null) 118 _relax(now->par); 119 _pushdown(now); 120 } 121 122 inline void _splay(Node* now,Node* goal) 123 { 124 _relax(now); 125 while (now->par != goal) 126 { 127 if (now->par->par == goal) 128 { 129 _rot(now); 130 break; 131 } 132 if (now->S() == now->par->S()) 133 { 134 _rot(now->par); 135 _rot(now); 136 } 137 else 138 { 139 _rot(now); 140 _rot(now); 141 } 142 } 143 if (goal == &null) 144 root=now; 145 } 146 147 inline Node* _select(int v) 148 { 149 Node* now=root; 150 while (1) 151 { 152 _pushdown(now); 153 if (now->s[0]->size+1 == v) 154 return now; 155 if (v <= now->s[0]->size) 156 now=now->s[0]; 157 else 158 { 159 v-=now->s[0]->size+1; 160 now=now->s[1]; 161 } 162 } 163 } 164 165 inline void insert(int* r,int pos,int len) 166 { 167 Node* p=_select(pos+1); 168 Node* q=_select(pos+2); 169 _splay(p,&null); 170 _splay(q,root); 171 Node* now=new_Node(r[1]); 172 (now->par=q)->s[0]=now; 173 Node* par=now; 174 for (int i=2;i<=len;i++) 175 { 176 now=new_Node(r[i]); 177 (now->par=par)->s[1]=now; 178 now->size=len-i+1; 179 par=now; 180 } 181 _splay(now,&null); 182 } 183 184 inline void del(int pos,int len) 185 { 186 Node* p=_select(pos); 187 Node* q=_select(pos+len+1); 188 _splay(p,&null); 189 _splay(q,root); 190 erase(q->s[0]); 191 q->s[0]=&null; 192 _update(q); 193 _update(p); 194 } 195 196 inline void change(int pos,int len,int val) 197 { 198 Node* p=_select(pos); 199 Node* q=_select(pos+len+1); 200 _splay(p,&null); 201 _splay(q,root); 202 Node* now=q->s[0]; 203 now->lazy=now->v=val; 204 now->sum=val*now->size; 205 now->lmax=now->rmax=now->max=max(val,val*now->size); 206 _update(q); 207 _update(p); 208 } 209 210 inline void rot(int pos,int len) 211 { 212 Node* p=_select(pos); 213 Node* q=_select(pos+len+1); 214 _splay(p,&null); 215 _splay(q,root); 216 Node* now=q->s[0]; 217 now->rot^=1; 218 swap(now->lmax,now->rmax); 219 _update(q); 220 _update(p); 221 } 222 223 inline int query_sum(int pos,int len) 224 { 225 Node* p=_select(pos); 226 Node* q=_select(pos+len+1); 227 _splay(p,&null); 228 _splay(q,root); 229 return q->s[0]->sum; 230 } 231 232 inline int query_max() 233 { 234 Node* p=&t[0]; 235 Node* q=&t[1]; 236 _splay(p,&null); 237 _splay(q,root); 238 return q->s[0]->max; 239 } 240 241 void travel(Node* now) 242 { 243 _pushdown(now); 244 if (now->s[0] != &null) 245 travel(now->s[0]); 246 printf("%d ",now->v); 247 if (now->s[1] != &null) 248 travel(now->s[1]); 249 } 250 }t; 251 252 int a[maxn]; 253 254 int main() 255 { 256 int n,_; 257 scanf("%d%d",&n,&_); 258 for (int i=1;i<=n;i++) 259 scanf("%d",&a[i]); 260 t.insert(a,0,n); 261 while (_--) 262 { 263 char s[20]; 264 int pos,len; 265 scanf("%s",s); 266 if (s[0] == 'I') 267 { 268 scanf("%d%d",&pos,&len); 269 for (int i=1;i<=len;i++) 270 scanf("%d",&a[i]); 271 t.insert(a,pos,len); 272 } 273 if (s[0] == 'D') 274 { 275 scanf("%d%d",&pos,&len); 276 t.del(pos,len); 277 } 278 if (s[0] == 'M' && s[2] == 'K') 279 { 280 int x; 281 scanf("%d%d%d",&pos,&len,&x); 282 t.change(pos,len,x); 283 } 284 if (s[0] == 'R') 285 { 286 scanf("%d%d",&pos,&len); 287 t.rot(pos,len); 288 } 289 if (s[0] == 'G') 290 { 291 scanf("%d%d",&pos,&len); 292 printf("%d\n",t.query_sum(pos,len)); 293 } 294 if (s[0] == 'M' && s[2] == 'X') 295 printf("%d\n",t.query_max()); 296 } 297 return 0; 298 }
bzoj1503
裸的平衡树,可以打全局标记
1 #include <cstdio> 2 3 const int maxn=100010; 4 5 int n,min,add; 6 7 struct Node 8 { 9 int size,v; 10 Node *s[2]; 11 Node() 12 { 13 size=v=0; 14 } 15 }; 16 17 struct sbt 18 { 19 Node t[maxn],null; 20 Node *root; 21 int ne; 22 23 sbt() 24 { 25 ne=0; 26 null.s[0]=null.s[1]=&null; 27 root=&null; 28 } 29 30 inline void _rot(Node* &now,int l) 31 { 32 int r=!l; 33 Node *s=now->s[l]; 34 now->s[l]=s->s[r]; 35 s->s[r]=now; 36 s->size=now->size; 37 now->size=now->s[0]->size+now->s[1]->size+1; 38 now=s; 39 } 40 41 void _maintain(Node* &now,int l) 42 { 43 int r=!l; 44 if (now->s[l]->s[l]->size > now->s[r]->size) 45 _rot(now,l); 46 else 47 { 48 if (now->s[l]->s[r]->size > now->s[r]->size) 49 { 50 _rot(now->s[l],r); 51 _rot(now,l); 52 } 53 else 54 return; 55 } 56 _maintain(now->s[0],0); 57 _maintain(now->s[1],1); 58 _maintain(now,0); 59 _maintain(now,1); 60 } 61 62 void insert(Node* &now,int v) 63 { 64 if (now == &null) 65 { 66 now=&t[++ne]; 67 now->v=v; 68 now->size=1; 69 now->s[0]=now->s[1]=&null; 70 return; 71 } 72 now->size++; 73 if (v < now->v) 74 insert(now->s[0],v); 75 else 76 insert(now->s[1],v); 77 _maintain(now,v >= now->v); 78 } 79 80 void del(Node* &now) 81 { 82 if (now == &null) 83 return; 84 if (now->v+add < min) 85 { 86 now=now->s[1]; 87 del(now); 88 } 89 else 90 { 91 del(now->s[0]); 92 now->size=now->s[0]->size+now->s[1]->size+1; 93 } 94 } 95 96 inline int find(int v) 97 { 98 Node* now=root; 99 while (1) 100 { 101 if (now == &null) 102 return -1; 103 if (now->s[1]->size+1 == v) 104 return now->v+add; 105 if (v <= now->s[1]->size) 106 now=now->s[1]; 107 else 108 { 109 v-=now->s[1]->size+1; 110 now=now->s[0]; 111 } 112 } 113 } 114 115 void travel(Node* now) 116 { 117 if (now->s[0] != &null) 118 travel(now->s[0]); 119 printf("%d\n",now->v+add); 120 if (now->s[1] != &null) 121 travel(now->s[1]); 122 } 123 }t; 124 125 int main() 126 { 127 // freopen("1.in","r",stdin); 128 // freopen("1.out","w",stdout); 129 scanf("%d%d",&n,&min); 130 char s[2]; 131 int x; 132 while (n--) 133 { 134 scanf("%s%d",s,&x); 135 if (s[0] == 'I') 136 if (x >= min) 137 t.insert(t.root,x-add); 138 if (s[0] == 'A') 139 add+=x; 140 if (s[0] == 'S') 141 { 142 add-=x; 143 t.del(t.root); 144 } 145 if (s[0] == 'F') 146 printf("%d\n",t.find(x)); 147 } 148 printf("%d\n",t.ne-t.root->size); 149 return 0; 150 }
bzoj1507
1269弱化版,我同学get的时候爆栈了的说。。。表示不能理解。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 3*1024*1024 7 8 struct Node 9 { 10 char ch; 11 int size; 12 Node *s[2],*par; 13 14 inline bool S() 15 { 16 return this == par->s[1]; 17 } 18 }; 19 20 struct splay 21 { 22 Node t[maxn],null; 23 Node *root; 24 int ne; 25 26 splay() 27 { 28 null.s[0]=null.s[1]=null.par=&null; 29 null.size=null.ch=0; 30 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].ch='s'; 31 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].ch='b'; 32 ne=2; 33 root=&t[0]; 34 } 35 36 inline Node* new_Node() 37 { 38 Node* now=&t[ne++]; 39 now->s[0]=now->s[1]=now->par=&null; 40 return now; 41 } 42 43 inline void _update(Node* now) 44 { 45 now->size=now->s[0]->size+now->s[1]->size+1; 46 } 47 48 inline void _rot(Node* now) 49 { 50 Node* p=now->par; 51 int l=now->S(),r=!l; 52 (p->s[l]=now->s[r])->par=p; 53 now->par=p->par; 54 if (p->par != &null) 55 p->par->s[p->S()]=now; 56 (now->s[r]=p)->par=now; 57 _update(p); 58 _update(now); 59 } 60 61 inline void _splay(Node* now,Node* goal) 62 { 63 while (now->par != goal) 64 { 65 if (now->par->par == goal) 66 { 67 _rot(now); 68 break; 69 } 70 if (now->par->S() == now->S()) 71 { 72 _rot(now->par); 73 _rot(now); 74 } 75 else 76 { 77 _rot(now); 78 _rot(now); 79 } 80 } 81 if (goal == &null) 82 root=now; 83 } 84 85 inline Node* _select(int v) 86 { 87 Node* now=root; 88 while (1) 89 { 90 if (now->s[0]->size+1 == v) 91 return now; 92 if (v <= now->s[0]->size) 93 now=now->s[0]; 94 else 95 { 96 v-=now->s[0]->size+1; 97 now=now->s[1]; 98 } 99 } 100 } 101 102 inline void insert(int pos,int len) 103 { 104 Node* p=_select(pos+1); 105 Node* q=_select(pos+2); 106 _splay(p,&null); 107 _splay(q,root); 108 static char s[maxn]; 109 for (int i=1;i<=len;i++) 110 while (s[i]=getchar(),s[i] == '\n' || s[i] == '\r'); 111 Node* now=new_Node(); 112 now->ch=s[1]; 113 (q->s[0]=now)->par=q; 114 now->size=len; 115 q->size+=len; 116 p->size+=len; 117 Node* par=now; 118 for (int i=2;i<=len;i++) 119 { 120 Node* now=new_Node(); 121 now->ch=s[i]; 122 (par->s[1]=now)->par=par; 123 now->size=len-i+1; 124 par=now; 125 } 126 _splay(now,&null); 127 } 128 129 inline void del(int pos,int len) 130 { 131 Node* p=_select(pos+1); 132 Node* q=_select(min(root->size,pos+len+2)); 133 _splay(p,&null); 134 _splay(q,root); 135 q->s[0]=&null; 136 _update(q); 137 _update(p); 138 } 139 140 void travel(Node* now) 141 { 142 if (now->s[0] != &null) 143 travel(now->s[0]); 144 putchar(now->ch); 145 if (now->s[1] != &null) 146 travel(now->s[1]); 147 } 148 149 inline void get(int pos,int len) 150 { 151 Node* p=_select(pos+1); 152 Node* q=_select(min(pos+len+2,root->size)); 153 _splay(p,&null); 154 _splay(q,root); 155 travel(q->s[0]); 156 } 157 }t; 158 159 int main() 160 { 161 int pos=0; 162 int _; 163 scanf("%d",&_); 164 while (_--) 165 { 166 char s[10]; 167 int x; 168 scanf("%s",s); 169 if (s[0] == 'M') 170 { 171 scanf("%d",&x); 172 pos=x; 173 } 174 if (s[0] == 'I') 175 { 176 scanf("%d",&x); 177 t.insert(pos,x); 178 } 179 if (s[0] == 'D') 180 { 181 scanf("%d",&x); 182 t.del(pos,x); 183 } 184 if (s[0] == 'G') 185 { 186 scanf("%d",&x); 187 t.get(pos,x); 188 puts(""); 189 } 190 if (s[0] == 'P') 191 pos--; 192 if (s[0] == 'N') 193 pos++; 194 } 195 return 0; 196 }
bzoj1588
又是裸的平衡树。。。
1 #include <cstdio> 2 3 const int maxn=100010; 4 const int inf=0x3f3f3f3f; 5 6 struct Node 7 { 8 Node* s[2]; 9 int size,v; 10 }; 11 12 struct sbt 13 { 14 Node t[maxn],null; 15 Node* root; 16 int ne; 17 18 sbt() 19 { 20 null.s[0]=null.s[1]=&null; 21 null.v=null.size=0; 22 ne=0; 23 root=&null; 24 } 25 26 inline void _rot(Node* &now,int l) 27 { 28 int r=!l; 29 Node* s=now->s[l]; 30 s->size=now->size; 31 now->s[l]=s->s[r]; 32 s->s[r]=now; 33 now->size=now->s[0]->size+now->s[1]->size+1; 34 now=s; 35 } 36 37 void _maintain(Node* &now,int l) 38 { 39 int r=!l; 40 if (now->s[l]->s[l]->size > now->s[r]->size) 41 _rot(now,l); 42 else 43 { 44 if (now->s[l]->s[r]->size > now->s[r]->size) 45 { 46 _rot(now->s[l],r); 47 _rot(now,l); 48 } 49 else 50 return; 51 } 52 _maintain(now->s[0],0); 53 _maintain(now->s[1],1); 54 _maintain(now,0); 55 _maintain(now,1); 56 } 57 58 void insert(Node* &now,int v) 59 { 60 if (now == &null) 61 { 62 now=&t[ne++]; 63 now->v=v; 64 now->size=1; 65 now->s[0]=now->s[1]=&null; 66 return; 67 } 68 now->size++; 69 if (v >= now->v) 70 insert(now->s[1],v); 71 else 72 insert(now->s[0],v); 73 _maintain(now,v >= now->v); 74 } 75 76 inline int pred(int v) 77 { 78 int ans=-inf; 79 Node* now=root; 80 while (1) 81 { 82 if (now == &null) 83 break; 84 if (v < now->v) 85 now=now->s[0]; 86 else 87 { 88 ans=now->v; 89 now=now->s[1]; 90 } 91 } 92 return ans; 93 } 94 95 inline int suc(int v) 96 { 97 int ans=inf; 98 Node* now=root; 99 while (1) 100 { 101 if (now == &null) 102 break; 103 if (v > now->v) 104 now=now->s[1]; 105 else 106 { 107 ans=now->v; 108 now=now->s[0]; 109 } 110 } 111 return ans; 112 } 113 }t; 114 115 inline int min(int a,int b) 116 { 117 if (a < b) 118 return a; 119 return b; 120 } 121 122 inline int abs(int x) 123 { 124 if (x >= 0) 125 return x; 126 return -x; 127 } 128 129 int main() 130 { 131 int n,x; 132 int sum=0; 133 scanf("%d",&n); 134 scanf("%d",&x); 135 sum=x; 136 t.insert(t.root,x); 137 for (int i=2;i<=n;i++) 138 { 139 x=0; 140 scanf("%d",&x); 141 sum+=min(abs(x-t.pred(x)),abs(t.suc(x)-x)); 142 t.insert(t.root,x); 143 } 144 printf("%d",sum); 145 return 0; 146 }
bzoj1610(已隐藏)
水题不能多说,凑AC数用的。。。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 210 8 #define eps 1e-8 9 10 int cnt=0; 11 double a[maxn*maxn],x[maxn],y[maxn]; 12 13 int main() 14 { 15 int n; 16 scanf("%d",&n); 17 for (int i=1;i<=n;i++) 18 scanf("%lf%lf",&x[i],&y[i]); 19 int ans=0; 20 for (int i=1;i<n;i++) 21 for (int j=i+1;j<=n;j++) 22 if (fabs(x[i]-x[j]) < eps) 23 ans=1; 24 else 25 a[++cnt]=(y[i]-y[j])/(x[i]-x[j]); 26 sort(a+1,a+cnt+1); 27 a[0]=a[1]-1; 28 for (int i=1;i<=cnt;i++) 29 if (a[i]-a[i-1] > eps) 30 ans++; 31 printf("%d\n",ans); 32 return 0; 33 }
bzoj1612(已隐藏)
两边BFS即可,注意重新加边时的清零
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 110 5 #define maxm 5010 6 7 struct edge 8 { 9 int to; 10 edge *next; 11 }e[maxm],*head[maxn]; 12 13 int ne=0; 14 int q[maxn]; 15 int from[maxm],to[maxm]; 16 int now[maxn]; 17 bool flag[maxn]; 18 19 inline void add_edge(int from,int to) 20 { 21 e[ne].to=to; 22 e[ne].next=head[from]; 23 head[from]=&e[ne++]; 24 } 25 26 inline int bfs(int now) 27 { 28 int op=0,cls=1; 29 q[1]=now; 30 int ans=0; 31 while (op != cls) 32 { 33 int x=q[++op]; 34 for (edge *p=head[x];p;p=p->next) 35 if (!flag[p->to]) 36 { 37 flag[p->to]=1; 38 q[++cls]=p->to; 39 ans++; 40 } 41 } 42 return ans; 43 } 44 45 int main() 46 { 47 int n,m; 48 scanf("%d%d",&n,&m); 49 for (int i=1;i<=m;i++) 50 scanf("%d%d",&from[i],&to[i]); 51 for (int i=1;i<=m;i++) 52 add_edge(from[i],to[i]); 53 for (int i=1;i<=n;i++) 54 { 55 memset(flag,0,sizeof(flag)); 56 flag[i]=1; 57 now[i]+=bfs(i); 58 } 59 memset(head,0,sizeof(head)); 60 ne=0; 61 for (int i=1;i<=m;i++) 62 add_edge(to[i],from[i]); 63 int ans=0; 64 for (int i=1;i<=n;i++) 65 { 66 memset(flag,0,sizeof(flag)); 67 flag[i]=1; 68 now[i]+=bfs(i); 69 if (now[i] == n-1) 70 ans++; 71 } 72 printf("%d\n",ans); 73 return 0; 74 }
bzoj1616(已隐藏)
暴力DP
1 #include <cstdio> 2 3 #define maxn 110 4 5 const int fx[]={0,1,0,-1}; 6 const int fy[]={1,0,-1,0}; 7 8 bool map[maxn][maxn]; 9 int f[maxn][maxn][20]; 10 11 int main() 12 { 13 int n,m,t,sx,sy,tx,ty; 14 scanf("%d%d%d",&n,&m,&t); 15 for (int i=1;i<=n;i++) 16 for (int j=1;j<=m;j++) 17 { 18 char ch; 19 while (ch=getchar(),ch != '.' && ch != '*'); 20 if (ch == '.') 21 map[i][j]=1; 22 else 23 map[i][j]=0; 24 } 25 scanf("%d%d%d%d",&sx,&sy,&tx,&ty); 26 f[sx][sy][0]=1; 27 for (int k=1;k<=t;k++) 28 for (int i=1;i<=n;i++) 29 for (int j=1;j<=m;j++) 30 if (map[i][j]) 31 for (int p=0;p<4;p++) 32 { 33 int x=i+fx[p],y=j+fy[p]; 34 if (map[x][y]) 35 f[i][j][k]+=f[x][y][k-1]; 36 } 37 printf("%d\n",f[tx][ty][t]); 38 return 0; 39 }
bzoj1633(已隐藏)
挺好玩的字符串+DP
1 #include <cstdio> 2 #include <cstring> 3 4 #define inf 0x3f3f3f3f 5 #define maxn 610 6 7 int n,len,l[maxn]; 8 char s[maxn]; 9 char ch[maxn][30]; 10 int f[maxn]; 11 12 inline int min(int a,int b) 13 { 14 return a < b ? a : b; 15 } 16 17 inline int find(int pos,int x) 18 { 19 int l1=pos; 20 int l2=0; 21 while (l1 < len && l2 < l[x]) 22 { 23 if (s[l1] == ch[x][l2]) 24 l2++; 25 l1++; 26 } 27 if (l2 < l[x]) 28 return inf; 29 return l1; 30 } 31 32 int main() 33 { 34 scanf("%d%d",&n,&len); 35 scanf("%s",s); 36 for (int i=1;i<=n;i++) 37 { 38 scanf("%s",ch[i]); 39 l[i]=strlen(ch[i]); 40 } 41 memset(f,0,sizeof(f)); 42 for (int i=len-1;i>=0;i--) 43 { 44 f[i]=f[i+1]+1; 45 for (int j=1;j<=n;j++) 46 { 47 int pos=find(i,j); 48 if (pos != inf) 49 f[i]=min(f[i],f[pos]+pos-i-l[j]); 50 } 51 } 52 printf("%d\n",f[0]); 53 return 0; 54 }
bzoj1636(已隐藏)
裸st
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 50010 7 8 int n,m; 9 int a[maxn]; 10 int bit[30]; 11 int fmax[maxn][20],fmin[maxn][20]; 12 13 inline int max(int a,int b) 14 { 15 return a > b ? a : b; 16 } 17 18 inline int min(int a,int b) 19 { 20 return a < b ? a : b; 21 } 22 23 inline void st_pre() 24 { 25 for (int i=1;i<=n;i++) 26 fmin[i][0]=fmax[i][0]=a[i]; 27 int k=lower_bound(bit,bit+20,n)-bit; 28 for (int j=1;j<=k;j++) 29 for (int i=1;i+bit[j]-1 <= n;i++) 30 { 31 fmin[i][j]=min(fmin[i][j-1],fmin[i+bit[j-1]][j-1]); 32 fmax[i][j]=max(fmax[i][j-1],fmax[i+bit[j-1]][j-1]); 33 } 34 } 35 36 inline int query(int l,int r) 37 { 38 int len=r-l+1; 39 int k=lower_bound(bit,bit+20,len)-bit; 40 int Max=max(fmax[l][k-1],fmax[r-bit[k-1]+1][k-1]); 41 int Min=min(fmin[l][k-1],fmin[r-bit[k-1]+1][k-1]); 42 return Max-Min; 43 } 44 45 int main() 46 { 47 bit[0]=1; 48 for (int i=1;i<=20;i++) 49 bit[i]=bit[i-1]+bit[i-1]; 50 scanf("%d%d",&n,&m); 51 for (int i=1;i<=n;i++) 52 scanf("%d",&a[i]); 53 st_pre(); 54 for (int i=1;i<=m;i++) 55 { 56 int x,y; 57 scanf("%d%d",&x,&y); 58 if (x > y) 59 x^=y^=x^=y; 60 printf("%d\n",query(x,y)); 61 } 62 return 0; 63 }
bzoj1666(已隐藏)
普及组?这道题拿来玩压代码长度游戏还不错。。。
1 #include <cstdio> 2 3 int ans=0,x; 4 5 int main() 6 { 7 scanf("%d",&x); 8 while (x != 1) 9 { 10 if (x & 1) 11 (x*=3)+=1; 12 else 13 x>>=1; 14 ans++; 15 } 16 printf("%d\n",ans); 17 return 0; 18 }
bzoj1668(已隐藏)
水水的DP
1 #include <cstdio> 2 3 #define maxn 110 4 5 int n,m; 6 int a[maxn][maxn],f[maxn][maxn]; 7 8 inline int max(int a,int b) 9 { 10 return a > b ? a : b; 11 } 12 13 inline int min(int a,int b) 14 { 15 return a < b ? a : b; 16 } 17 18 int main() 19 { 20 scanf("%d%d",&n,&m); 21 for (int i=1;i<=n;i++) 22 for (int j=1;j<=m;j++) 23 scanf("%d",&a[i][j]); 24 for (int i=1;i<=m;i++) 25 for (int j=1;j<=min(i,n);j++) 26 f[j][i]=max(max(f[j-1][i-1],f[j][i-1]),f[j+1][i-1])+a[j][i]; 27 printf("%d\n",f[n][m]); 28 return 0; 29 }
bzoj1699(已隐藏)
还是st。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 50010 7 8 int n,m; 9 int a[maxn]; 10 int bit[30]; 11 int fmax[maxn][20],fmin[maxn][20]; 12 13 inline int max(int a,int b) 14 { 15 return a > b ? a : b; 16 } 17 18 inline int min(int a,int b) 19 { 20 return a < b ? a : b; 21 } 22 23 inline void st_pre() 24 { 25 for (int i=1;i<=n;i++) 26 fmin[i][0]=fmax[i][0]=a[i]; 27 int k=lower_bound(bit,bit+20,n)-bit; 28 for (int j=1;j<=k;j++) 29 for (int i=1;i+bit[j]-1 <= n;i++) 30 { 31 fmin[i][j]=min(fmin[i][j-1],fmin[i+bit[j-1]][j-1]); 32 fmax[i][j]=max(fmax[i][j-1],fmax[i+bit[j-1]][j-1]); 33 } 34 } 35 36 inline int query(int l,int r) 37 { 38 int len=r-l+1; 39 int k=lower_bound(bit,bit+20,len)-bit; 40 int Max=max(fmax[l][k-1],fmax[r-bit[k-1]+1][k-1]); 41 int Min=min(fmin[l][k-1],fmin[r-bit[k-1]+1][k-1]); 42 return Max-Min; 43 } 44 45 int main() 46 { 47 bit[0]=1; 48 for (int i=1;i<=20;i++) 49 bit[i]=bit[i-1]+bit[i-1]; 50 scanf("%d%d",&n,&m); 51 for (int i=1;i<=n;i++) 52 scanf("%d",&a[i]); 53 st_pre(); 54 for (int i=1;i<=m;i++) 55 { 56 int x,y; 57 scanf("%d%d",&x,&y); 58 if (x > y) 59 x^=y^=x^=y; 60 printf("%d\n",query(x,y)); 61 } 62 return 0; 63 }
bzoj1717(已隐藏)
后缀数组+二分
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 int n,k; 6 int a[maxn],sa[maxn]; 7 8 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 9 10 int cmp(int *r,int a,int b,int l) 11 {return r[a]==r[b]&&r[a+l]==r[b+l];} 12 13 inline void da(int *r,int *sa,int n,int m) 14 { 15 int i,j,p,*x=wa,*y=wb,*t; 16 for(i=0;i<m;i++) ws[i]=0; 17 for(i=0;i<n;i++) ws[x[i]=r[i]]++; 18 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 19 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 20 for(j=1,p=1;p<n;j*=2,m=p) 21 { 22 for(p=0,i=n-j;i<n;i++) y[p++]=i; 23 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 24 for(i=0;i<n;i++) wv[i]=x[y[i]]; 25 for(i=0;i<m;i++) ws[i]=0; 26 for(i=0;i<n;i++) ws[wv[i]]++; 27 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 28 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; 29 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 30 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 31 } 32 return; 33 } 34 35 int rank[maxn],height[maxn]; 36 37 inline void calheight(int *r,int *sa,int n) 38 { 39 int i,j,k=0; 40 for(i=1;i<=n;i++) rank[sa[i]]=i; 41 for(i=0;i<n;height[rank[i++]]=k) 42 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 43 return; 44 } 45 46 inline void read(int &x) 47 { 48 char ch; 49 while (ch=getchar(),ch > '9' || ch < '0'); 50 x=ch-'0'; 51 while (ch=getchar(),ch <= '9' && ch >= '0') 52 x=(x<<3)+x+x+ch-'0'; 53 } 54 55 inline bool check(int x) 56 { 57 int ans=1; 58 for (int i=1;i<=n;i++) 59 if (height[i] < x) 60 ans=1; 61 else 62 { 63 ans++; 64 if (ans >= k) 65 return 1; 66 } 67 return 0; 68 } 69 70 int main() 71 { 72 read(n); 73 read(k); 74 for (int i=0;i<n;i++) 75 read(a[i]); 76 da(a,sa,n+1,maxn); 77 calheight(a,sa,n); 78 int l=1,r=n; 79 int ans=-1; 80 while (l < r) 81 { 82 int mid=(l+r)>>1; 83 if (check(mid)) 84 { 85 ans=mid; 86 l=mid+1; 87 } 88 else 89 r=mid; 90 } 91 printf("%d\n",ans); 92 return 0; 93 }
bzoj1726(已隐藏)
spfa改一下即可
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 5010 5 #define maxm 200010 6 7 struct edge 8 { 9 int to,dist; 10 edge *next; 11 }e[maxm],*head[maxn]; 12 13 int ne=0; 14 int min[maxn],sec[maxn],flag[maxn],q[maxn]; 15 16 inline void add_edge(int from,int to,int dist) 17 { 18 e[ne].to=to; 19 e[ne].dist=dist; 20 e[ne].next=head[from]; 21 head[from]=&e[ne++]; 22 } 23 24 inline int _min(int a,int b) 25 { 26 return a < b ? a : b; 27 } 28 29 inline void spfa() 30 { 31 int op=0,cls=1; 32 q[1]=1; 33 memset(min,0x3f,sizeof(min)); 34 memset(sec,0x3f,sizeof(sec)); 35 min[1]=0; 36 flag[1]=1; 37 while (op != cls) 38 { 39 op++; 40 if (op == maxn) 41 op=0; 42 int x=q[op]; 43 flag[x]=0; 44 for (edge *p=head[x];p;p=p->next) 45 { 46 int minl=min[x]+p->dist; 47 int secl=sec[x]+p->dist; 48 if (minl >= sec[p->to]) 49 continue; 50 if (minl < min[p->to]) 51 { 52 sec[p->to]=_min(min[p->to],secl); 53 min[p->to]=minl; 54 } 55 else 56 { 57 if (minl > min[p->to]) 58 sec[p->to]=_min(minl,sec[p->to]); 59 else 60 { 61 if (minl == min[p->to]) 62 { 63 sec[p->to]=_min(secl,sec[p->to]); 64 if (sec[p->to] <= secl) 65 continue; 66 } 67 } 68 } 69 if (!flag[p->to]) 70 { 71 cls++; 72 if (cls == maxn) 73 cls=0; 74 q[cls]=p->to; 75 flag[p->to]=1; 76 } 77 } 78 } 79 } 80 81 int main() 82 { 83 int n,m; 84 scanf("%d%d",&n,&m); 85 for (int i=1;i<=m;i++) 86 { 87 int x,y,z; 88 scanf("%d%d%d",&x,&y,&z); 89 add_edge(x,y,z); 90 add_edge(y,x,z); 91 } 92 spfa(); 93 printf("%d\n",sec[n]); 94 return 0; 95 }
bzoj1797
dinic后在残量网络上求强联通。。。至今还不知道为什么是对的。。。太弱了
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 4010 8 #define maxm 60010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,flow,from; 14 edge *next,*part; 15 }e[maxm<<1],*head[maxn]; 16 17 int s,t; 18 int ne=0,time=0,cnt=0; 19 int q[maxn],d[maxn]; 20 int dfn[maxn],low[maxn],belong[maxn]; 21 int sta[maxn],top=0; 22 bool vis[maxn]; 23 24 inline void read(int &x) 25 { 26 char ch; 27 while (ch=getchar(),ch > '9' || ch < '0'); 28 x=ch-'0'; 29 while (ch=getchar(),ch <= '9' && ch >= '0') 30 x=(x<<3)+x+x+ch-'0'; 31 } 32 33 inline void add(int from,int to,int flow) 34 { 35 e[ne].to=to; 36 e[ne].from=from; 37 e[ne].flow=flow; 38 e[ne].next=head[from]; 39 head[from]=&e[ne++]; 40 } 41 42 inline void add_edge(int from,int to,int flow) 43 { 44 e[ne].part=&e[ne+1]; 45 e[ne+1].part=&e[ne]; 46 add(from,to,flow); 47 add(to,from,0); 48 } 49 50 inline bool bfs() 51 { 52 memset(d,-1,sizeof(d)); 53 int op=0,cls=1; 54 q[1]=s; 55 d[s]=0; 56 while (op != cls) 57 { 58 int x=q[++op]; 59 for (edge *p=head[x];p;p=p->next) 60 if (p->flow && d[p->to] == -1) 61 { 62 d[p->to]=d[x]+1; 63 q[++cls]=p->to; 64 } 65 } 66 return d[t] != -1; 67 } 68 69 int dfs(int now,int now_flow) 70 { 71 if (now == t) 72 return now_flow; 73 int out=now_flow; 74 for (edge *p=head[now];p;p=p->next) 75 if (p->flow && d[p->to] == d[now]+1 && out) 76 { 77 int f=dfs(p->to,min(p->flow,out)); 78 p->flow-=f; 79 p->part->flow+=f; 80 out-=f; 81 } 82 if (now_flow == out) 83 d[now]=-1; 84 return now_flow-out; 85 } 86 87 inline void dinic() 88 { 89 while (bfs()) 90 dfs(s,inf); 91 } 92 93 void tarjan(int now) 94 { 95 dfn[now]=low[now]=++time; 96 sta[++top]=now; 97 vis[now]=1; 98 for (edge *p=head[now];p;p=p->next) 99 if (p->flow) 100 { 101 if (!dfn[p->to]) 102 { 103 tarjan(p->to); 104 low[now]=min(low[now],low[p->to]); 105 } 106 else 107 if (vis[p->to]) 108 low[now]=min(low[now],dfn[p->to]); 109 } 110 if (dfn[now] == low[now]) 111 { 112 int v; 113 cnt++; 114 do 115 { 116 v=sta[top--]; 117 vis[v]=0; 118 belong[v]=cnt; 119 } 120 while (v != now); 121 } 122 } 123 124 int main() 125 { 126 int n,m; 127 read(n); 128 read(m); 129 read(s); 130 read(t); 131 for (int i=1;i<=m;i++) 132 { 133 int x,y,z; 134 read(x); 135 read(y); 136 read(z); 137 add_edge(x,y,z); 138 } 139 dinic(); 140 for (int i=1;i<=n;i++) 141 if (!dfn[i]) 142 tarjan(i); 143 for (int i=0;i<ne;i+=2) 144 if (!e[i].flow) 145 { 146 if (belong[e[i].from] == belong[e[i].to]) 147 puts("0 0"); 148 else 149 if (belong[e[i].from] == belong[s] && belong[e[i].to] == belong[t]) 150 puts("1 1"); 151 else 152 puts("1 0"); 153 } 154 else 155 puts("0 0"); 156 return 0; 157 }
bzoj1798
水水的线段树,乘的标记下放的时候把加的标记一起乘了就可以了
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 long long sum,lazy_add,lazy_mul; 8 Node() 9 { 10 sum=lazy_add=0; 11 lazy_mul=1; 12 } 13 }t[maxn<<2]; 14 15 long long p; 16 17 inline void _pushdown(long long l,long long r,long long rt) 18 { 19 long long mid=(l+r)>>1,add=t[rt].lazy_add,mul=t[rt].lazy_mul; 20 if (t[rt].lazy_mul != 1) 21 { 22 (t[rt<<1].lazy_mul*=mul)%=p; 23 (t[rt<<1|1].lazy_mul*=mul)%=p; 24 (t[rt<<1].lazy_add*=mul)%=p; 25 (t[rt<<1|1].lazy_add*=mul)%=p; 26 (t[rt<<1].sum*=mul)%=p; 27 (t[rt<<1|1].sum*=mul)%=p; 28 t[rt].lazy_mul=1; 29 } 30 if (t[rt].lazy_add) 31 { 32 (t[rt<<1].lazy_add+=add)%=p; 33 (t[rt<<1|1].lazy_add+=add)%=p; 34 (t[rt<<1].sum+=add*(mid-l+1))%=p; 35 (t[rt<<1|1].sum+=add*(r-mid))%=p; 36 t[rt].lazy_add=0; 37 } 38 } 39 40 inline void _update(long long rt) 41 { 42 t[rt].sum=(t[rt<<1].sum+t[rt<<1|1].sum)%p; 43 } 44 45 void add(long long l,long long r,long long rt,long long L,long long R,long long val) 46 { 47 if (l >= L && r <= R) 48 { 49 t[rt].lazy_add+=val; 50 t[rt].sum+=val*(r-l+1); 51 return; 52 } 53 _pushdown(l,r,rt); 54 long long mid=(l+r)>>1; 55 if (L <= mid) 56 add(l,mid,rt<<1,L,R,val); 57 if (R > mid) 58 add(mid+1,r,rt<<1|1,L,R,val); 59 _update(rt); 60 } 61 62 void mul(long long l,long long r,long long rt,long long L,long long R,long long val) 63 { 64 if (l >= L && r <= R) 65 { 66 (t[rt].lazy_add*=val)%=p; 67 (t[rt].lazy_mul*=val)%=p; 68 (t[rt].sum*=val)%=p; 69 return; 70 } 71 _pushdown(l,r,rt); 72 long long mid=(l+r)>>1; 73 if (L <= mid) 74 mul(l,mid,rt<<1,L,R,val); 75 if (R > mid) 76 mul(mid+1,r,rt<<1|1,L,R,val); 77 _update(rt); 78 } 79 80 long long query(long long l,long long r,long long rt,long long L,long long R) 81 { 82 if (l >= L && r <= R) 83 return t[rt].sum; 84 _pushdown(l,r,rt); 85 long long mid=(l+r)>>1,ans=0; 86 if (L <= mid) 87 ans+=query(l,mid,rt<<1,L,R); 88 if (R > mid) 89 ans+=query(mid+1,r,rt<<1|1,L,R); 90 return ans%p; 91 } 92 93 int main() 94 { 95 long long n; 96 scanf("%lld%lld",&n,&p); 97 for (long long i=1;i<=n;i++) 98 { 99 long long x; 100 scanf("%lld",&x); 101 add(1,n,1,i,i,x); 102 } 103 long long _; 104 scanf("%lld",&_); 105 while (_--) 106 { 107 long long x,y,z,w; 108 scanf("%lld%lld%lld",&x,&y,&z); 109 if (x == 1) 110 { 111 scanf("%lld",&w); 112 mul(1,n,1,y,z,w); 113 } 114 if (x == 2) 115 { 116 scanf("%lld",&w); 117 add(1,n,1,y,z,w); 118 } 119 if (x == 3) 120 printf("%lld\n",query(1,n,1,y,z)); 121 } 122 return 0; 123 }
bzoj1800
从O(n^4)到O(n)的做法都有,都是0ms。。。看心情吧
1 #include <cstdio> 2 3 #define maxn 25 4 5 int sum[maxn],a[maxn]; 6 7 int main() 8 { 9 int n; 10 scanf("%d",&n); 11 int len=0; 12 for (int i=1;i<=n;i++) 13 { 14 scanf("%d",&a[i]); 15 len+=a[i]; 16 sum[i]=sum[i-1]+a[i]; 17 } 18 int ans=0; 19 for (int i=1;i<n;i++) 20 for (int j=i+1;j<=n;j++) 21 if (sum[j]-sum[i] == len>>1) 22 ans++; 23 printf("%d\n",ans*(ans-1)/2); 24 return 0; 25 }
bzoj1816
二分一下即可
1 #include <cstdio> 2 3 #define maxn 55 4 #define inf 0x3f3f3f3f3f3fLL 5 6 long long n; 7 long long a[maxn]; 8 9 inline bool check(long long now,long long rest) 10 { 11 long long del=0; 12 bool flag=1; 13 for (long long i=1;i<=n;i++) 14 if (a[i] < now) 15 { 16 if (now-a[i] <= rest) 17 { 18 rest-=now-a[i]; 19 del+=now-a[i]; 20 } 21 else 22 { 23 flag=0; 24 break; 25 } 26 } 27 if (!flag) 28 return 0; 29 if (del > now) 30 return 0; 31 return 1; 32 } 33 34 int main() 35 { 36 long long m; 37 scanf("%lld%lld",&n,&m); 38 for (long long i=1;i<=n;i++) 39 scanf("%lld",&a[i]); 40 long long l=-1,r=inf,ans=0; 41 while (l < r) 42 { 43 long long mid=(l+r)>>1; 44 if (check(mid,m)) 45 { 46 ans=mid; 47 l=mid+1; 48 } 49 else 50 r=mid; 51 } 52 printf("%lld\n",ans); 53 return 0; 54 }
bzoj1821
贪心+并查集
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1010 8 9 int f[maxn],r[maxn]; 10 int x[maxn],y[maxn]; 11 12 struct Node 13 { 14 int f,t,dist; 15 }a[maxn*maxn]; 16 17 inline bool cmp(const Node a,const Node b) 18 { 19 return a.dist < b.dist; 20 } 21 22 int find(int x) 23 { 24 if (f[x] == x) 25 return x; 26 return f[x]=find(f[x]); 27 } 28 29 inline void _union(int x,int y) 30 { 31 if (r[x] <= r[y]) 32 { 33 f[x]=y; 34 r[y]+=r[x]; 35 } 36 else 37 { 38 f[y]=x; 39 r[x]+=r[y]; 40 } 41 } 42 43 int main() 44 { 45 int n,k; 46 scanf("%d%d",&n,&k); 47 for (int i=1;i<=n;i++) 48 { 49 scanf("%d%d",&x[i],&y[i]); 50 f[i]=i; 51 r[i]=1; 52 } 53 int cnt=n,ne=0; 54 for (int i=1;i<n;i++) 55 for (int j=i+1;j<=n;j++) 56 { 57 ne++; 58 a[ne].f=i; 59 a[ne].t=j; 60 a[ne].dist=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); 61 } 62 sort(a+1,a+ne+1,cmp); 63 for (int i=1;i<=ne;i++) 64 { 65 int x=find(a[i].f),y=find(a[i].t); 66 if (x == y) 67 continue; 68 if (cnt == k) 69 { 70 printf("%.2lf\n",sqrt(a[i].dist)); 71 return 0; 72 } 73 _union(x,y); 74 cnt--; 75 } 76 return 0; 77 }
bzoj1827
很少的几道奶牛网没有被隐藏的题之一。。。树形DFS(还是不想管这个叫DP)
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct edge 6 { 7 long long to,dist; 8 edge *next; 9 }e[maxn<<1],*head[maxn]; 10 11 long long ne=0; 12 long long ans; 13 long long q[maxn],size[maxn],fa[maxn]; 14 15 inline void add_edge(long long from,long long to,long long dist) 16 { 17 e[ne].to=to; 18 e[ne].dist=dist; 19 e[ne].next=head[from]; 20 head[from]=&e[ne++]; 21 } 22 23 inline void read(long long &x) 24 { 25 x=0; 26 char ch; 27 while (ch=getchar(),ch > '9' || ch < '0'); 28 x=ch-'0'; 29 while (ch=getchar(),ch <= '9' && ch >= '0') 30 x=(x<<3)+x+x+ch-'0'; 31 } 32 33 inline void bfs() 34 { 35 long long op=0,cls=1; 36 q[1]=1; 37 while (op != cls) 38 { 39 long long x=q[++op]; 40 for (edge *p=head[x];p;p=p->next) 41 if (p->to != fa[x]) 42 { 43 fa[p->to]=x; 44 q[++cls]=p->to; 45 } 46 } 47 } 48 49 inline long long dfs(long long now) 50 { 51 long long ans=0; 52 for (edge *p=head[now];p;p=p->next) 53 if (p->to != fa[now]) 54 { 55 ans+=dfs(p->to)+p->dist*size[p->to]; 56 size[now]+=size[p->to]; 57 } 58 return ans; 59 } 60 61 inline long long dfs(long long now,long long now_ans) 62 { 63 if (now_ans < ans) 64 ans=now_ans; 65 for (edge *p=head[now];p;p=p->next) 66 if (p->to != fa[now]) 67 dfs(p->to,now_ans+p->dist*(size[1]-size[p->to]*2)); 68 } 69 70 int main() 71 { 72 long long n; 73 read(n); 74 for (long long i=1;i<=n;i++) 75 read(size[i]); 76 for (long long i=1;i<n;i++) 77 { 78 long long x,y,z; 79 read(x); 80 read(y); 81 read(z); 82 add_edge(x,y,z); 83 add_edge(y,x,z); 84 } 85 bfs(); 86 long long now=dfs(1); 87 ans=now; 88 dfs(1,now); 89 printf("%lld\n",ans); 90 return 0; 91 }
bzoj1834
dinic后残量网络上加一些边跑费用流
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 2010 8 #define maxm 10010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,flow,cost; 14 edge *part,*next; 15 }e[maxm<<1],*head[maxn],*prev[maxn]; 16 17 int n,m,k; 18 int ne=0,s,t; 19 int q[maxn],d[maxn]; 20 int from[maxm],to[maxm],flow[maxm],cost[maxm]; 21 bool flag[maxn]; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 inline bool bfs() 41 { 42 int op=0,cls=1; 43 memset(d,-1,sizeof(d)); 44 q[1]=s; 45 d[s]=0; 46 while (op != cls) 47 { 48 int x=q[++op]; 49 for (edge *p=head[x];p;p=p->next) 50 if (p->flow && d[p->to] == -1) 51 { 52 q[++cls]=p->to; 53 d[p->to]=d[x]+1; 54 } 55 } 56 return d[t] != -1; 57 } 58 59 int dfs(int now,int now_flow) 60 { 61 if (now == t) 62 return now_flow; 63 int out=now_flow; 64 for (edge *p=head[now];p;p=p->next) 65 if (p->flow && d[p->to] == d[now]+1 && out) 66 { 67 int f=dfs(p->to,min(p->flow,out)); 68 p->flow-=f; 69 p->part->flow+=f; 70 out-=f; 71 } 72 if (out == now_flow) 73 d[now]=-1; 74 return now_flow-out; 75 } 76 77 inline int dinic() 78 { 79 int ans=0; 80 while (bfs()) 81 ans+=dfs(s,inf); 82 return ans; 83 } 84 85 inline bool spfa() 86 { 87 int op=0,cls=1; 88 memset(flag,0,sizeof(flag)); 89 memset(d,0x3f,sizeof(d)); 90 flag[s]=1; 91 d[s]=0; 92 q[1]=s; 93 while (op != cls) 94 { 95 op++; 96 if (op == maxn) 97 op=0; 98 int x=q[op]; 99 flag[x]=0; 100 for (edge *p=head[x];p;p=p->next) 101 if (p->flow && d[x]+p->cost < d[p->to]) 102 { 103 d[p->to]=d[x]+p->cost; 104 prev[p->to]=p->part; 105 if (!flag[p->to]) 106 { 107 cls++; 108 if (cls == maxn) 109 cls=0; 110 q[cls]=p->to; 111 flag[p->to]=1; 112 } 113 } 114 } 115 return d[t] != inf; 116 } 117 118 inline int agument() 119 { 120 int f=inf,ans=0; 121 for (edge *p=prev[t];p;p=prev[p->to]) 122 f=min(f,p->part->flow); 123 for (edge *p=prev[t];p;p=prev[p->to]) 124 { 125 p->flow+=f; 126 p->part->flow-=f; 127 ans+=p->part->cost*f; 128 } 129 return ans; 130 } 131 132 inline int min_cost() 133 { 134 int ans=0; 135 while (spfa()) 136 ans+=agument(); 137 return ans; 138 } 139 140 int main() 141 { 142 scanf("%d%d%d",&n,&m,&k); 143 for (int i=1;i<=m;i++) 144 { 145 scanf("%d%d%d%d",&from[i],&to[i],&flow[i],&cost[i]); 146 add_edge(from[i],to[i],flow[i],0); 147 } 148 s=1; 149 t=n; 150 printf("%d ",dinic()); 151 for (int i=1;i<=m;i++) 152 add_edge(from[i],to[i],inf,cost[i]); 153 s=0; 154 add_edge(0,1,k,0); 155 printf("%d\n",min_cost()); 156 return 0; 157 }
bzoj1854
枚举加边网络流T掉之后就写了个并查集过了。。。
1 #include <cstdio> 2 3 #define maxn 10010 4 5 int f[maxn],edge[maxn]; 6 int n; 7 8 int find(int x) 9 { 10 if (f[x] == x) 11 return x; 12 return f[x]=find(f[x]); 13 } 14 15 inline void _union(int a,int b) 16 { 17 int x=find(a); 18 int y=find(b); 19 if (x > y) 20 { 21 int t; 22 t=x,x=y,y=t; 23 } 24 if (x == y) 25 edge[x]++; 26 else 27 { 28 edge[x]+=edge[y]+1; 29 f[y]=x; 30 } 31 } 32 33 int main() 34 { 35 //freopen("1.in","r",stdin); 36 //freopen("1.out","w",stdout); 37 scanf("%d",&n); 38 for (int i=1;i<=maxn;i++) 39 f[i]=i; 40 for (int i=1;i<=n;i++) 41 { 42 int x,y; 43 scanf("%d%d",&x,&y); 44 _union(x,y); 45 } 46 for (int i=1;i<=maxn;i++) 47 { 48 if (edge[find(i)]) 49 edge[find(i)]--; 50 else 51 { 52 printf("%d\n",i-1); 53 break; 54 } 55 } 56 return 0; 57 }
bzoj1855
单调队列优化的DP
1 #include <cstdio> 2 3 #define maxn 2010 4 #define inf 0x3f3f3f3f 5 6 int t,maxp,w; 7 int f[maxn][maxn],as[maxn],ap[maxn],bs[maxn],bp[maxn]; 8 int q1[maxn],q2[maxn],pos[maxn]; 9 10 inline int max(int a,int b) 11 { 12 return a > b ? a : b; 13 } 14 15 int main() 16 { 17 scanf("%d%d%d",&t,&maxp,&w); 18 for (int i=1;i<=t;i++) 19 scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]); 20 for (int i=1;i<=w+1;i++) 21 for (int j=1;j<=maxp;j++) 22 f[i][j]=-inf; 23 for (int i=w+2;i<=t;i++) 24 { 25 for (int j=0;j<=maxp;j++) 26 { 27 f[i][j]=f[i-1][j]; 28 q1[j]=f[i-w-1][j]+ap[i-w-1]*j; 29 q2[j]=f[i-w-1][j]+bp[i-w-1]*j; 30 } 31 int op,cls; 32 op=cls=1; 33 pos[1]=0; 34 for (int j=1;j<=maxp;j++) 35 { 36 if (pos[op] < j-as[i-w-1]) 37 op++; 38 f[i][j]=max(f[i][j],q1[pos[op]]-ap[i-w-1]*j); 39 while (op <= cls && q1[j] > q1[pos[cls]]) 40 cls--; 41 pos[++cls]=j; 42 } 43 op=cls=1; 44 pos[1]=maxp; 45 for (int j=maxp-1;j>=0;j--) 46 { 47 if (pos[op] > j+bs[i-w-1]) 48 op++; 49 f[i][j]=max(f[i][j],q2[pos[op]]-bp[i-w-1]*j); 50 while (op <= cls && q2[j] > q2[pos[cls]]) 51 cls--; 52 pos[++cls]=j; 53 } 54 } 55 int ans=0; 56 for (int i=1;i<=t;i++) 57 for (int j=0;j<=maxp;j++) 58 { 59 if (j <= bs[i]) 60 ans=max(ans,f[i][j]+bp[i]*j); 61 else 62 ans=max(ans,f[i][j]+bp[i]*bs[i]); 63 } 64 printf("%d\n",ans); 65 return 0; 66 }
bzoj1858
比较难写的线段树,加了个读入优化就rank1了。。。(已被艹)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 struct Node 9 { 10 int sum,lmax,rmax,max,lmin,rmin,min,lazy; 11 }t[maxn<<2]; 12 13 inline void read(int &x) 14 { 15 char ch; 16 while (ch=getchar(),ch > '9' || ch < '0'); 17 x=ch-'0'; 18 while (ch=getchar(),ch <= '9' && ch >= '0') 19 x=(x<<3)+x+x+ch-'0'; 20 } 21 22 inline void _pushdown(int l,int r,int rt) 23 { 24 if (t[rt].lazy == -1) 25 return; 26 int mid=(l+r)>>1; 27 if (t[rt].lazy == 0) 28 { 29 t[rt].lazy=-1; 30 t[rt<<1].lazy=t[rt<<1|1].lazy=0; 31 t[rt<<1].lmin=t[rt<<1].rmin=t[rt<<1].min=mid-l+1; 32 t[rt<<1|1].lmin=t[rt<<1|1].rmin=t[rt<<1|1].min=r-mid; 33 t[rt<<1].lmax=t[rt<<1].rmax=t[rt<<1].max=t[rt<<1|1].lmax=t[rt<<1|1].rmax=t[rt<<1|1].max=0; 34 t[rt<<1].sum=t[rt<<1|1].sum=0; 35 return; 36 } 37 if (t[rt].lazy == 1) 38 { 39 t[rt].lazy=-1; 40 t[rt<<1].lazy=t[rt<<1|1].lazy=1; 41 t[rt<<1].lmax=t[rt<<1].rmax=t[rt<<1].max=mid-l+1; 42 t[rt<<1|1].lmax=t[rt<<1|1].rmax=t[rt<<1|1].max=r-mid; 43 t[rt<<1].lmin=t[rt<<1].rmin=t[rt<<1].min=t[rt<<1|1].lmin=t[rt<<1|1].rmin=t[rt<<1|1].min=0; 44 t[rt<<1].sum=mid-l+1; 45 t[rt<<1|1].sum=r-mid; 46 return; 47 } 48 if (t[rt].lazy == 2) 49 { 50 t[rt].lazy=-1; 51 t[rt<<1].lazy=1-t[rt<<1].lazy; 52 t[rt<<1|1].lazy=1-t[rt<<1|1].lazy; 53 swap(t[rt<<1].lmax,t[rt<<1].lmin); 54 swap(t[rt<<1].rmax,t[rt<<1].rmin); 55 swap(t[rt<<1].max,t[rt<<1].min); 56 swap(t[rt<<1|1].lmax,t[rt<<1|1].lmin); 57 swap(t[rt<<1|1].rmax,t[rt<<1|1].rmin); 58 swap(t[rt<<1|1].max,t[rt<<1|1].min); 59 t[rt<<1].sum=mid-l+1-t[rt<<1].sum; 60 t[rt<<1|1].sum=r-mid-t[rt<<1|1].sum; 61 } 62 } 63 64 inline void _update(int l,int r,int rt) 65 { 66 int mid=(l+r)>>1; 67 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum; 68 if (t[rt<<1].sum == mid-l+1) 69 t[rt].lmax=mid-l+1+t[rt<<1|1].lmax; 70 else 71 t[rt].lmax=t[rt<<1].lmax; 72 if (!t[rt<<1].sum) 73 t[rt].lmin=mid-l+1+t[rt<<1|1].lmin; 74 else 75 t[rt].lmin=t[rt<<1].lmin; 76 if (t[rt<<1|1].sum == r-mid) 77 t[rt].rmax=r-mid+t[rt<<1].rmax; 78 else 79 t[rt].rmax=t[rt<<1|1].rmax; 80 if (!t[rt<<1|1].sum) 81 t[rt].rmin=r-mid+t[rt<<1].rmin; 82 else 83 t[rt].rmin=t[rt<<1|1].rmin; 84 t[rt].max=max(max(t[rt<<1].max,t[rt<<1|1].max),t[rt<<1].rmax+t[rt<<1|1].lmax); 85 t[rt].min=max(max(t[rt<<1].min,t[rt<<1|1].min),t[rt<<1].rmin+t[rt<<1|1].lmin); 86 } 87 88 void build(int l,int r,int rt) 89 { 90 t[rt].lazy=-1; 91 if (l == r) 92 { 93 read(t[rt].sum); 94 if (t[rt].sum) 95 t[rt].lmax=t[rt].rmax=t[rt].max=1; 96 else 97 t[rt].lmin=t[rt].rmin=t[rt].min=1; 98 return; 99 } 100 int mid=(l+r)>>1; 101 build(l,mid,rt<<1); 102 build(mid+1,r,rt<<1|1); 103 _update(l,r,rt); 104 } 105 106 void insert(int l,int r,int rt,int L,int R,int add) 107 { 108 if (l >= L && r <= R) 109 { 110 if (add == 2) 111 t[rt].lazy=1-t[rt].lazy; 112 else 113 t[rt].lazy=add; 114 if (add == 0) 115 { 116 t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].sum=0; 117 t[rt].min=t[rt].lmin=t[rt].rmin=r-l+1; 118 } 119 if (add == 1) 120 { 121 t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].sum=r-l+1; 122 t[rt].min=t[rt].lmin=t[rt].rmin=0; 123 } 124 if (add == 2) 125 { 126 t[rt].sum=r-l+1-t[rt].sum; 127 swap(t[rt].max,t[rt].min); 128 swap(t[rt].lmax,t[rt].lmin); 129 swap(t[rt].rmax,t[rt].rmin); 130 } 131 return; 132 } 133 _pushdown(l,r,rt); 134 int mid=(l+r)>>1; 135 if (L <= mid) 136 insert(l,mid,rt<<1,L,R,add); 137 if (R > mid) 138 insert(mid+1,r,rt<<1|1,L,R,add); 139 _update(l,r,rt); 140 } 141 142 int query(int l,int r,int rt,int L,int R) 143 { 144 if (l != r) 145 _pushdown(l,r,rt); 146 if (l == L && r == R) 147 return t[rt].sum; 148 int mid=(l+r)>>1; 149 if (R <= mid) 150 return query(l,mid,rt<<1,L,R); 151 else 152 if (L > mid) 153 return query(mid+1,r,rt<<1|1,L,R); 154 else 155 return query(l,mid,rt<<1,L,mid)+query(mid+1,r,rt<<1|1,mid+1,R); 156 } 157 158 int query_l(int l,int r,int rt,int L,int R) 159 { 160 if (l != r) 161 _pushdown(l,r,rt); 162 if (l == L && r == R) 163 return t[rt].lmax; 164 if (t[rt].sum == r-l+1) 165 return R-L+1; 166 if (!t[rt].sum) 167 return 0; 168 int mid=(l+r)>>1; 169 if (R <= mid) 170 return query_l(l,mid,rt<<1,L,R); 171 if (t[rt<<1].sum == mid-l+1) 172 return mid-l+1+query_l(mid+1,r,rt<<1|1,mid+1,R); 173 return query_l(l,mid,rt<<1,L,mid); 174 } 175 176 int query_r(int l,int r,int rt,int L,int R) 177 { 178 if (l != r) 179 _pushdown(l,r,rt); 180 if (l == L && r == R) 181 return t[rt].rmax; 182 if (t[rt].sum == r-l+1) 183 return R-L+1; 184 if (!t[rt].sum) 185 return 0; 186 int mid=(l+r)>>1; 187 if (L > mid) 188 return query_r(mid+1,r,rt<<1|1,L,R); 189 if (t[rt<<1|1].sum == r-mid) 190 return r-mid+query_r(l,mid,rt<<1,L,mid); 191 return query_r(mid+1,r,rt<<1|1,mid+1,R); 192 } 193 194 int query_all(int l,int r,int rt,int L,int R) 195 { 196 if (l != r) 197 _pushdown(l,r,rt); 198 if (l == L && r == R) 199 return t[rt].max; 200 if (t[rt].sum == r-l+1) 201 return R-L+1; 202 if (!t[rt].sum) 203 return 0; 204 int mid=(l+r)>>1; 205 if (L > mid) 206 return query_all(mid+1,r,rt<<1|1,L,R); 207 else 208 if (R <= mid) 209 return query_all(l,mid,rt<<1,L,R); 210 else 211 return max(max(query_all(l,mid,rt<<1,L,mid),query_all(mid+1,r,rt<<1|1,mid+1,R)),query_r(l,mid,rt<<1,L,mid)+query_l(mid+1,r,rt<<1|1,mid+1,R)); 212 } 213 214 int main() 215 { 216 int n,m; 217 read(n); 218 read(m); 219 build(1,n,1); 220 while (m--) 221 { 222 int x,y,z; 223 read(x); 224 read(y); 225 read(z); 226 y++; 227 z++; 228 if (x == 0) 229 insert(1,n,1,y,z,0); 230 if (x == 1) 231 insert(1,n,1,y,z,1); 232 if (x == 2) 233 insert(1,n,1,y,z,2); 234 if (x == 3) 235 printf("%d\n",query(1,n,1,y,z)); 236 if (x == 4) 237 printf("%d\n",query_all(1,n,1,y,z)); 238 } 239 return 0; 240 }
bzoj1861
比较蛋疼的splay
1 #include <cstdio> 2 3 #define maxn 80010 4 5 int n; 6 int a[maxn]; 7 8 struct Node 9 { 10 int size,num; 11 Node *s[2],*par; 12 }; 13 14 struct splay 15 { 16 Node t[maxn],null; 17 Node *root,*pos[maxn]; 18 int ne; 19 20 splay() 21 { 22 null.s[0]=null.s[1]=null.par=&null; 23 null.size=0; 24 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].num=0; 25 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].num=0; 26 ne=1; 27 root=&t[0]; 28 } 29 30 inline void _update(Node* now) 31 { 32 if (now == &null) 33 return; 34 now->size=now->s[0]->size+now->s[1]->size+1; 35 } 36 37 inline void _rot(Node* now,int l) 38 { 39 int r=!l; 40 Node* p=now->par; 41 Node* s=now->s[l]; 42 (now->s[l]=s->s[r])->par=now; 43 (s->s[r]=now)->par=s; 44 s->par=p; 45 if (p != &null) 46 p->s[now == p->s[1]]=s; 47 _update(now); 48 _update(s); 49 } 50 51 inline void _splay(Node* now,Node* goal) 52 { 53 while (now->par != goal) 54 { 55 Node* p=now->par; 56 Node* g=p->par; 57 bool dp=now == p->s[1]; 58 bool dg=p == g->s[1]; 59 if (g == goal) 60 { 61 _rot(p,dp); 62 break; 63 } 64 if (dp == dg) 65 { 66 _rot(g,dg); 67 _rot(p,dp); 68 } 69 else 70 { 71 _rot(p,dp); 72 _rot(g,dg); 73 } 74 } 75 if (goal == &null) 76 root=now; 77 } 78 79 inline Node* _select(int v) 80 { 81 Node* now=root; 82 while (1) 83 { 84 if (now == &null) 85 return now; 86 if (now->s[0]->size+1 == v) 87 return now; 88 if (v <= now->s[0]->size) 89 now=now->s[0]; 90 else 91 { 92 v-=now->s[0]->size+1; 93 now=now->s[1]; 94 } 95 } 96 } 97 98 inline void build(int n) 99 { 100 ne++; 101 t[1].s[0]=&t[ne]; 102 t[ne].s[0]=&null; 103 t[ne].s[1]=&t[ne+1]; 104 t[ne].num=a[1]; 105 t[ne].size=n; 106 t[ne].par=&t[1]; 107 pos[a[1]]=&t[ne]; 108 for (int i=2;i<n;i++) 109 { 110 ne++; 111 t[ne].size=n-i+1; 112 t[ne].s[0]=&null; 113 t[ne].par=&t[ne-1]; 114 t[ne].s[1]=&t[ne+1]; 115 t[ne].num=a[i]; 116 pos[a[i]]=&t[ne]; 117 } 118 ne++; 119 t[ne].s[0]=t[ne].s[1]=&null; 120 t[ne].par=&t[ne-1]; 121 t[ne].num=a[n]; 122 t[ne].size=1; 123 pos[a[n]]=&t[ne]; 124 _update(root->s[1]); 125 _update(root); 126 } 127 128 inline void top(int s) 129 { 130 Node* now=pos[s]; 131 _splay(now,&null); 132 int r=now->s[0]->size+1; 133 Node* p=_select(r-1); 134 Node* q=_select(r+1); 135 _splay(p,&null); 136 _splay(q,root); 137 q->s[0]=&null; 138 q->size--; 139 p->size--; 140 p=_select(2); 141 _splay(p,&null); 142 (p->s[0]->s[1]=now)->par=p->s[0]; 143 now->s[0]=now->s[1]=&null; 144 p->s[0]->size++; 145 p->size++; 146 } 147 148 inline void bottom(int s) 149 { 150 Node* now=pos[s]; 151 _splay(now,&null); 152 int r=now->s[0]->size+1; 153 Node* p=_select(r-1); 154 Node* q=_select(r+1); 155 _splay(p,&null); 156 _splay(q,root); 157 q->s[0]=&null; 158 q->size--; 159 p->size--; 160 p=_select(n); 161 _splay(p,&null); 162 (p->s[1]->s[0]=now)->par=p->s[1]; 163 now->s[0]=now->s[1]=&null; 164 p->s[1]->size++; 165 p->size++; 166 } 167 168 inline void insert(int s,int t) 169 { 170 if (!t) 171 return; 172 Node* now=pos[s]; 173 _splay(now,&null); 174 int r=now->s[0]->size+1; 175 Node* p=_select(r-1); 176 Node* q=_select(r+1); 177 _splay(p,&null); 178 _splay(q,root); 179 q->s[0]=&null; 180 q->size--; 181 p->size--; 182 if (t == 1) 183 { 184 p=_select(r); 185 q=_select(r+1); 186 _splay(p,&null); 187 _splay(q,root); 188 (q->s[0]=now)->par=q; 189 now->s[0]=now->s[1]=&null; 190 q->size++; 191 p->size++; 192 } 193 else 194 { 195 p=_select(r-2); 196 q=_select(r-1); 197 _splay(p,&null); 198 _splay(q,root); 199 (q->s[0]=now)->par=q; 200 now->s[0]=now->s[1]=&null; 201 q->size++; 202 p->size++; 203 } 204 } 205 206 inline int ask(int s) 207 { 208 Node* now=pos[s]; 209 _splay(now,&null); 210 return now->s[0]->size-1; 211 } 212 213 inline int query(int v) 214 { 215 Node* now=_select(v+1); 216 return now->num; 217 } 218 219 void travel(Node* now) 220 { 221 if (now->s[0] != &null) 222 travel(now->s[0]); 223 printf("%d ",now->num); 224 if (now->s[1] != &null) 225 travel(now->s[1]); 226 } 227 }t; 228 229 int main() 230 { 231 int m; 232 scanf("%d%d",&n,&m); 233 for (int i=1;i<=n;i++) 234 scanf("%d",&a[i]); 235 t.build(n); 236 while (m--) 237 { 238 char ch[10]; 239 int x,y; 240 scanf("%s%d",ch,&x); 241 if (ch[0] == 'T') 242 t.top(x); 243 if (ch[0] == 'B') 244 t.bottom(x); 245 if (ch[0] == 'I') 246 { 247 scanf("%d",&y); 248 t.insert(x,y); 249 } 250 if (ch[0] == 'A') 251 printf("%d\n",t.ask(x)); 252 if (ch[0] == 'Q') 253 printf("%d\n",t.query(x)); 254 } 255 return 0; 256 }
bzoj1876
python水掉
1 def gcd(a, b): 2 while b!=0 : 3 if a % b == 0: 4 return b 5 else: 6 c=a%b 7 a=b 8 b=c 9 x = int(raw_input()) 10 y = int(raw_input()) 11 print(gcd(x,y))
bzoj1877
经典的拆点费用流
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1010 8 #define maxm 200010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,flow,cost; 14 edge *next,*part; 15 }e[maxm],*head[maxn],*prev[maxn]; 16 17 int s,t; 18 int ne=0; 19 int q[maxn],d[maxn]; 20 bool flag[maxn]; 21 int flow=0; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 inline bool spfa() 41 { 42 memset(d,0x3f,sizeof(d)); 43 memset(flag,0,sizeof(flag)); 44 int op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 flag[s]=1; 48 while (op != cls) 49 { 50 op=op == maxn-1 ? 0 : op+1; 51 int x=q[op]; 52 for (edge *p=head[x];p;p=p->next) 53 if (p->flow && d[p->to] > d[x]+p->cost) 54 { 55 d[p->to]=d[x]+p->cost; 56 prev[p->to]=p->part; 57 if (!flag[p->to]) 58 { 59 if (op != cls) 60 { 61 int now=op == maxn-1 ? 0 : op+1; 62 if (d[p->to] < d[q[now]]) 63 { 64 q[op]=p->to; 65 op=op == 0 ? maxn-1 : op-1; 66 } 67 else 68 { 69 cls=cls == maxn-1 ? 0 : cls+1; 70 q[cls]=p->to; 71 } 72 } 73 else 74 { 75 cls=cls == maxn-1 ? 0 : cls+1; 76 q[cls]=p->to; 77 } 78 flag[p->to]=1; 79 } 80 } 81 flag[x]=0; 82 } 83 return d[t] != inf; 84 } 85 86 inline int agument() 87 { 88 int f=inf,ans=0; 89 for (edge *p=prev[t];p;p=prev[p->to]) 90 f=min(f,p->part->flow); 91 flow+=f; 92 for (edge *p=prev[t];p;p=prev[p->to]) 93 { 94 p->flow+=f; 95 p->part->flow-=f; 96 ans+=p->part->cost*f; 97 } 98 return ans; 99 } 100 101 inline int min_cost() 102 { 103 int ans=0; 104 while (spfa()) 105 ans+=agument(); 106 return ans; 107 } 108 109 int l[maxn],r[maxn]; 110 111 int main() 112 { 113 int n,m; 114 scanf("%d%d",&n,&m); 115 s=1,t=2; 116 l[1]=1; 117 r[n]=2; 118 int cnt=2; 119 for (int i=2;i<n;i++) 120 { 121 r[i]=++cnt; 122 l[i]=++cnt; 123 } 124 for (int i=1;i<=m;i++) 125 { 126 int x,y,z; 127 scanf("%d%d%d",&x,&y,&z); 128 if (x == n || y == 1) 129 continue; 130 add_edge(l[x],r[y],1,z); 131 } 132 for (int i=2;i<n;i++) 133 add_edge(r[i],l[i],1,0); 134 int ans=min_cost(); 135 printf("%d %d\n",flow,ans); 136 return 0; 137 }
bzoj1878
离线树状数组,其实可以在线主席树,但是懒得写了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 50010 7 #define maxm 200010 8 9 struct query 10 { 11 int l,r,id; 12 inline bool operator < (const query b) const 13 { 14 return l < b.l; 15 } 16 }q[maxm]; 17 18 int n; 19 int a[maxn],b[maxn]; 20 int bit[maxn]; 21 int now[maxn],next[maxn]; 22 int ans[maxm]; 23 char s[10]; 24 25 inline void read(int &x) 26 { 27 x=0; 28 char ch; 29 while (ch=getchar(),ch > '9' || ch < '0'); 30 x=ch-'0'; 31 while (ch=getchar(),ch <= '9' && ch >= '0') 32 x=(x<<3)+x+x+ch-'0'; 33 } 34 35 inline void bit_update(int now,int add) 36 { 37 for (;now<=n;now+=now&-now) 38 bit[now]+=add; 39 } 40 41 inline int query(int now) 42 { 43 int ans=0; 44 for (;now;now-=now&-now) 45 ans+=bit[now]; 46 return ans; 47 } 48 49 inline void writeln(int x) 50 { 51 int cnt=0; 52 while (x) 53 { 54 s[++cnt]=(x%10)+'0'; 55 x/=10; 56 } 57 for (int i=cnt;i;i--) 58 putchar(s[i]); 59 puts(""); 60 } 61 62 int main() 63 { 64 read(n); 65 for (int i=1;i<=n;i++) 66 { 67 read(a[i]); 68 b[i]=a[i]; 69 } 70 sort(b+1,b+n+1); 71 int size=unique(b+1,b+n+1)-b-1; 72 for (int i=1;i<=n;i++) 73 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 74 for (int i=1;i<=size;i++) 75 now[i]=n+1; 76 for (int i=n;i;i--) 77 { 78 next[i]=now[a[i]]; 79 now[a[i]]=i; 80 } 81 for (int i=1;i<=size;i++) 82 bit_update(now[i],1); 83 int m; 84 read(m); 85 for (int i=1;i<=m;i++) 86 { 87 read(q[i].l); 88 read(q[i].r); 89 q[i].id=i; 90 } 91 sort(q+1,q+m+1); 92 int nowl=1; 93 for (int i=1;i<=m;i++) 94 { 95 while (nowl < q[i].l) 96 { 97 bit_update(nowl,-1); 98 bit_update(next[nowl],1); 99 nowl++; 100 } 101 ans[q[i].id]=query(q[i].r); 102 } 103 for (int i=1;i<=m;i++) 104 writeln(ans[i]); 105 return 0; 106 }
bzoj1901
树状数组套主席树模板题
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn=100010; 7 const int maxm=3000010; 8 9 struct Node 10 { 11 Node* s[2]; 12 int size; 13 Node() 14 { 15 size=0; 16 } 17 }t[maxm],*root[maxn],*L[30],*R[30],null; 18 19 int ne=0,size,n,m; 20 int lsize,rsize; 21 int a[maxn],b[maxn]; 22 int p[maxn],q[maxn],k[maxn]; 23 char ch[maxn][3]; 24 25 Node* build(int val,int l,int r) 26 { 27 Node* now=&t[ne++]; 28 now->s[0]=now->s[1]=&null; 29 now->size=1; 30 if (l == r) 31 return now; 32 int mid=(l+r)>>1; 33 if (val <= mid) 34 now->s[0]=build(val,l,mid); 35 else 36 now->s[1]=build(val,mid+1,r); 37 return now; 38 } 39 40 void update(Node* now,int val,int l,int r,int flag) 41 { 42 while (1) 43 { 44 now->size+=flag; 45 if (l == r) 46 break; 47 int mid=(l+r)>>1; 48 if (val <= mid) 49 { 50 if (now->s[0] == &null) 51 { 52 now->s[0]=build(val,l,mid); 53 return; 54 } 55 else 56 { 57 now=now->s[0]; 58 r=mid; 59 } 60 } 61 else 62 { 63 if (now->s[1] == &null) 64 { 65 now->s[1]=build(val,mid+1,r); 66 return; 67 } 68 else 69 { 70 now=now->s[1]; 71 l=mid+1; 72 } 73 } 74 } 75 } 76 77 void bit_update(int now,int val,int flag) 78 { 79 for (;now <= n;now+=now & -now) 80 { 81 if (root[now] == &null) 82 root[now]=build(val,1,size); 83 else 84 update(root[now],val,1,size,flag); 85 } 86 } 87 88 int query(int l,int r,int k) 89 { 90 if (l == r) 91 return l; 92 int lsum=0,rsum=0,del,mid=(l+r)>>1; 93 for (int i=1;i<=lsize;i++) 94 lsum+=L[i]->s[0]->size; 95 for (int i=1;i<=rsize;i++) 96 rsum+=R[i]->s[0]->size; 97 del=rsum-lsum; 98 if (k <= del) 99 { 100 for (int i=1;i <= lsize;i++) 101 L[i]=L[i]->s[0]; 102 for (int i=1;i <= rsize;i++) 103 R[i]=R[i]->s[0]; 104 return query(l,mid,k); 105 } 106 else 107 { 108 for (int i=1;i <= lsize;i++) 109 L[i]=L[i]->s[1]; 110 for (int i=1;i <= rsize;i++) 111 R[i]=R[i]->s[1]; 112 return query(mid+1,r,k-del); 113 } 114 } 115 116 int ask(int l,int r,int k) 117 { 118 lsize=rsize=0; 119 if (!l) 120 L[++lsize]=&null; 121 else 122 for (;l > 0;l-=l & -l) 123 L[++lsize]=root[l]; 124 for (;r > 0;r-=r & -r) 125 R[++rsize]=root[r]; 126 return query(1,size,k); 127 } 128 129 int main() 130 { 131 null.s[0]=null.s[1]=&null; 132 scanf("%d%d",&n,&m); 133 for (int i=1;i <= n;i++) 134 { 135 scanf("%d",&a[i]); 136 b[i]=a[i]; 137 } 138 size=n; 139 for (int i=1;i <= m;i++) 140 { 141 scanf("%s%d%d",ch[i],&p[i],&q[i]); 142 if (ch[i][0] == 'Q') 143 scanf("%d",&k[i]); 144 else 145 b[++size]=q[i]; 146 } 147 sort(b+1,b+size+1); 148 size=unique(b+1,b+size+1)-b-1; 149 for (int i=1;i <= n;i++) 150 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 151 for (int i=1;i <= n;i++) 152 root[i]=&null; 153 for (int i=1;i <= n;i++) 154 bit_update(i,a[i],1); 155 for (int i=1;i <= m;i++) 156 { 157 if (ch[i][0] == 'Q') 158 printf("%d\n",b[ask(p[i]-1,q[i],k[i])]); 159 else 160 { 161 int pos=lower_bound(b+1,b+size+1,q[i])-b; 162 bit_update(p[i],a[p[i]],-1); 163 a[p[i]]=pos; 164 bit_update(p[i],a[p[i]],1); 165 } 166 } 167 return 0; 168 }
bzoj1911
斜率优化的DP
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 #ifdef unix 6 #define LL "%lld" 7 #else 8 #define LL "%I64d" 9 #endif 10 11 inline long long sqr(long long x) 12 { 13 return x*x; 14 } 15 16 long long n,a,b,c; 17 long long sum[maxn],dp[maxn],q[maxn]; 18 19 inline long long calc(long long x,long long y) 20 { 21 return dp[x]+a*sqr(sum[x])-b*sum[x]-dp[y]-a*sqr(sum[y])+b*sum[y]; 22 } 23 24 inline void read(int &x) 25 { 26 char ch; 27 while (ch=getchar(),ch > '9' || ch < '0'); 28 x=ch-'0'; 29 while (ch=getchar(),ch <= '9' && ch >= '0') 30 x=(x<<3)+x+x+ch-'0'; 31 } 32 33 int main() 34 { 35 scanf(LL LL LL LL,&n,&a,&b,&c); 36 for (int i=1;i<=n;i++) 37 { 38 int x; 39 read(x); 40 sum[i]=sum[i-1]+x; 41 } 42 int op=0,cls=0; 43 for (int i=1;i<=n;i++) 44 { 45 while (op < cls) 46 { 47 if (calc(q[op+1],q[op]) >= 2*a*sum[i]*(sum[q[op+1]]-sum[q[op]])) 48 op++; 49 else 50 break; 51 } 52 dp[i]=dp[q[op]]+a*sqr(sum[i]-sum[q[op]])+b*(sum[i]-sum[q[op]])+c; 53 while (op < cls) 54 { 55 if (calc(q[cls],q[cls-1])*(sum[i]-sum[q[cls]]) <= calc(i,q[cls])*(sum[q[cls]]-sum[q[cls-1]])) 56 cls--; 57 else 58 break; 59 } 60 q[++cls]=i; 61 } 62 printf(LL,dp[n]); 63 return 0; 64 }
bzoj1912
对于K=1,两次DFS找直径即可,对于K=2,在做完第一步之后把经过的边边权赋为-1,再找一次最长链即可
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 100010 5 #define inf 0x3f3f3f3f 6 7 struct edge 8 { 9 int to,dist; 10 edge *next,*part; 11 }e[maxn<<1],*head[maxn],*prev[maxn]; 12 13 int ne=0,n; 14 int q[maxn],d[maxn],fa[maxn]; 15 int max[maxn],sec[maxn]; 16 bool flag[maxn]; 17 18 inline int min(int a,int b) 19 { 20 return a < b ? a : b; 21 } 22 23 inline void add(int from,int to,int dist) 24 { 25 e[ne].to=to; 26 e[ne].dist=dist; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void add_edge(int from,int to,int dist) 32 { 33 e[ne].part=&e[ne+1]; 34 e[ne+1].part=&e[ne]; 35 add(from,to,dist); 36 add(to,from,dist); 37 } 38 39 inline int bfs(int s) 40 { 41 int op=0,cls=1; 42 memset(d,0,sizeof(d)); 43 memset(flag,0,sizeof(flag)); 44 q[1]=s; 45 flag[s]=1; 46 while (op != cls) 47 { 48 int x=q[++op]; 49 flag[x]=1; 50 for (edge *p=head[x];p;p=p->next) 51 if (!flag[p->to]) 52 { 53 d[p->to]=d[x]+p->dist; 54 prev[p->to]=p->part; 55 fa[p->to]=x; 56 q[++cls]=p->to; 57 } 58 } 59 int _max=0,now=s; 60 for (int i=1;i<=n;i++) 61 if (d[i] > _max) 62 { 63 _max=d[i]; 64 now=i; 65 } 66 return now; 67 } 68 69 int main() 70 { 71 int k; 72 int x,y; 73 scanf("%d%d",&n,&k); 74 for (int i=1;i<n;i++) 75 { 76 scanf("%d%d",&x,&y); 77 add_edge(x,y,1); 78 } 79 x=bfs(1); 80 memset(prev,0x0,sizeof(prev)); 81 y=bfs(x); 82 prev[x]=NULL; 83 int ans=(n-1)*2-d[y]+1; 84 if (k == 1) 85 { 86 printf("%d\n",ans); 87 return 0; 88 } 89 for (edge *p=prev[y];p;p=prev[p->to]) 90 p->dist=p->part->dist=-1; 91 for (int i=1;i<=n;i++) 92 max[i]=sec[i]=-inf; 93 for (int i=n;i;i--) 94 { 95 int x=q[i]; 96 bool leaf=1; 97 for (edge *p=head[x];p;p=p->next) 98 if (p->to != fa[x]) 99 { 100 leaf=0; 101 int _max=p->dist+max[p->to]; 102 if (_max >= max[x]) 103 { 104 sec[x]=max[x]; 105 max[x]=_max; 106 } 107 else 108 if (_max > sec[x]) 109 sec[x]=_max; 110 } 111 if (leaf) 112 max[x]=sec[x]=0; 113 } 114 int _ans=inf; 115 for (int i=1;i<=n;i++) 116 _ans=min(_ans,ans-max[i]-sec[i]+1); 117 printf("%d\n",_ans); 118 return 0; 119 }
bzoj1927
比较难想(对我这个蒟蒻来说)的拆点费用流,这种建图思路很多题都能用
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 2010 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow,cost; 16 edge *next,*part; 17 }e[maxm],*head[maxn],*prev[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 bool flag[maxn]; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 inline bool spfa() 41 { 42 memset(d,0x3f,sizeof(d)); 43 memset(flag,0,sizeof(flag)); 44 int op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 flag[s]=1; 48 while (op != cls) 49 { 50 op=op == maxn-1 ? 0 : op+1; 51 int x=q[op]; 52 for (edge *p=head[x];p;p=p->next) 53 if (p->flow && d[p->to] > d[x]+p->cost) 54 { 55 d[p->to]=d[x]+p->cost; 56 prev[p->to]=p->part; 57 if (!flag[p->to]) 58 { 59 if (op != cls) 60 { 61 int now=op == maxn-1 ? 0 : op+1; 62 if (d[p->to] < d[q[now]]) 63 { 64 q[op]=p->to; 65 op=op == 0 ? maxn-1 : op-1; 66 } 67 else 68 { 69 cls=cls == maxn-1 ? 0 : cls+1; 70 q[cls]=p->to; 71 } 72 } 73 else 74 { 75 cls=cls == maxn-1 ? 0 : cls+1; 76 q[cls]=p->to; 77 } 78 flag[p->to]=1; 79 } 80 } 81 flag[x]=0; 82 } 83 return d[t] != inf; 84 } 85 86 inline int agument() 87 { 88 int f=inf,ans=0; 89 for (edge *p=prev[t];p;p=prev[p->to]) 90 f=min(f,p->part->flow); 91 for (edge *p=prev[t];p;p=prev[p->to]) 92 { 93 p->flow+=f; 94 p->part->flow-=f; 95 ans+=p->part->cost*f; 96 } 97 return ans; 98 } 99 100 inline int min_cost() 101 { 102 int ans=0; 103 while (spfa()) 104 ans+=agument(); 105 return ans; 106 } 107 108 int main() 109 { 110 int n,m; 111 scanf("%d%d",&n,&m); 112 for (int i=1;i<=n;i++) 113 { 114 int x; 115 scanf("%d",&x); 116 add_edge(s,i,1,x); 117 add_edge(i,t,1,0); 118 add_edge(s,i+n,1,0); 119 } 120 for (int i=1;i<=m;i++) 121 { 122 int x,y,z; 123 scanf("%d%d%d",&x,&y,&z); 124 if (x > y) 125 swap(x,y); 126 add_edge(x+n,y,1,z); 127 } 128 printf("%d\n",min_cost()); 129 return 0; 130 }
bzoj1934
最小割模型,我会说数据水到二分图(不加同一边的边)都能过?
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 1010 5 #define maxm 1000010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int to,flow; 11 edge *next,*part; 12 }e[maxm],*head[maxn]; 13 14 int ne=0,s=0,t=maxn-1; 15 int d[maxn],q[maxn],a[maxn]; 16 17 inline int min(int a,int b) 18 { 19 return a < b ? a : b; 20 } 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline void add_edge_other(int from,int to,int flow) 39 { 40 e[ne].part=&e[ne+1]; 41 e[ne+1].part=&e[ne]; 42 add(from,to,flow); 43 add(to,from,flow); 44 } 45 46 inline bool bfs() 47 { 48 memset(d,-1,sizeof(d)); 49 int op=0,cls=1; 50 q[1]=s; 51 d[s]=0; 52 while (op != cls) 53 { 54 int x=q[++op]; 55 for (edge *p=head[x];p;p=p->next) 56 if (p->flow && d[p->to] == -1) 57 { 58 d[p->to]=d[x]+1; 59 q[++cls]=p->to; 60 } 61 } 62 return d[t] != -1; 63 } 64 65 int dfs(int now,int now_flow) 66 { 67 if (now == t) 68 return now_flow; 69 int out=now_flow; 70 for (edge *p=head[now];p;p=p->next) 71 if (p->flow && d[p->to] == d[now]+1 && out) 72 { 73 int f=dfs(p->to,min(out,p->flow)); 74 p->flow-=f; 75 p->part->flow+=f; 76 out-=f; 77 } 78 if (now_flow == out) 79 d[now]=-1; 80 return now_flow-out; 81 } 82 83 inline int dinic() 84 { 85 int ans=0; 86 while (bfs()) 87 ans+=dfs(s,inf); 88 return ans; 89 } 90 91 int main() 92 { 93 int n,m; 94 scanf("%d%d",&n,&m); 95 for (int i=1;i<=n;i++) 96 scanf("%d",&a[i]); 97 for (int i=1;i<=m;i++) 98 { 99 int x,y; 100 scanf("%d%d",&x,&y); 101 if (a[x] == a[y]) 102 add_edge_other(x+a[x]*n,y+a[y]*n,1); 103 else 104 { 105 if (a[x] == 1) 106 x^=y^=x^=y; 107 add_edge(x,y+n,1); 108 } 109 } 110 for (int i=1;i<=n;i++) 111 { 112 add_edge(s,i,1); 113 add_edge(i+n,t,1); 114 } 115 printf("%d\n",dinic()); 116 return 0; 117 }
bzoj1937
orz the mst的弱化版,线性规划,直接套单纯形了,据说这道题的特殊性使得可以用KM做?
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 110 5 #define maxm 3010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int from,to,num; 11 edge *next; 12 }e[maxm],*head[maxn],*prev[maxn]; 13 14 int ne=0,cnt=0; 15 int n,m; 16 int q[maxn]; 17 int from[maxm],to[maxm],w[maxm],inc[maxm],dec[maxm],flag[maxm]; 18 int a[1010][15010]; 19 int next[maxn]; 20 bool vis[maxn]; 21 22 inline void add_edge(int from,int to,int num) 23 { 24 e[ne].to=to; 25 e[ne].from=from; 26 e[ne].num=num; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void find(int s,int t,int n) 32 { 33 int op=0,cls=1; 34 q[1]=s; 35 memset(vis,0,sizeof(vis)); 36 vis[s]=1; 37 prev[s]=0; 38 while (op != cls) 39 { 40 int x=q[++op]; 41 for (edge *p=head[x];p;p=p->next) 42 if (!vis[p->to]) 43 { 44 vis[p->to]=1; 45 prev[p->to]=p; 46 q[++cls]=p->to; 47 if (p->to == t) 48 break; 49 } 50 } 51 for (edge *p=prev[t];p;p=prev[p->from]) 52 { 53 int now=p->num; 54 cnt++; 55 a[now][cnt]=a[n][cnt]=1; 56 a[0][cnt]=w[now]-w[n]; 57 } 58 } 59 60 inline void pivot(int l,int e) 61 { 62 int t=0; 63 for(int i=0;i<=cnt;i++) 64 if(a[l][i]) 65 next[t]=i,t=i; 66 next[t]=-1; 67 for(int i=0;i<=m;i++) 68 { 69 if(a[i][e] == 0 || i == l) 70 continue; 71 for(int j=0;j!=-1;j=next[j]) 72 { 73 if(j == e) 74 continue; 75 a[i][j]-=a[l][j]*a[i][e]; 76 } 77 a[i][e]=-a[i][e]; 78 } 79 } 80 81 inline int simplex() 82 { 83 for(;;) 84 { 85 int e=0; 86 for(int i=1;i<=cnt;i++) 87 if(a[0][i] > 0) 88 { 89 e=i; 90 break; 91 } 92 if(!e) 93 return -a[0][0]; 94 int pos,ans=inf; 95 for(int i=1;i<=m;i++) 96 if(a[i][e] > 0 && a[i][0] < ans) 97 ans=a[i][0],pos = i; 98 pivot(pos,e); 99 } 100 } 101 102 inline void read(int &x) 103 { 104 char ch; 105 while (ch=getchar(),ch > '9' || ch < '0'); 106 x=ch-'0'; 107 while (ch=getchar(),ch <= '9' && ch >= '0') 108 x=(x<<3)+x+x+ch-'0'; 109 } 110 111 bool map[maxn][maxn]; 112 113 int main() 114 { 115 read(n); 116 read(m); 117 for (int i=1;i<=m;i++) 118 { 119 read(from[i]); 120 read(to[i]); 121 read(w[i]); 122 } 123 for (int i=1;i<n;i++) 124 { 125 int x=0,y=0; 126 read(x); 127 read(y); 128 map[x][y]=map[y][x]=1; 129 } 130 for (int i=1;i<=m;i++) 131 { 132 inc[i]=dec[i]=1; 133 if (map[from[i]][to[i]]) 134 { 135 add_edge(from[i],to[i],i); 136 add_edge(to[i],from[i],i); 137 flag[i]=1; 138 } 139 } 140 for (int i=1;i<=m;i++) 141 if (!flag[i]) 142 find(from[i],to[i],i); 143 for (int i=1;i<=m;i++) 144 a[i][0]=1; 145 printf("%d\n",simplex()); 146 return 0; 147 }
bzoj1970
读懂题就是裸的高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #ifdef unix 11 #define ll "%lld" 12 #else 13 #define ll "%I64d" 14 #endif 15 class wkint { 16 private: 17 long long a[1510]; 18 int len; 19 public: 20 wkint(); 21 wkint(int t); 22 void read(); 23 void print(); 24 wkint operator + (const wkint &t) const; 25 wkint operator - (const wkint &t) const; 26 wkint operator * (const wkint &t) const; 27 wkint operator * (const int &t) const; 28 wkint operator ^ (const int &t) const; 29 wkint operator / (const int &t) const; 30 int operator % (const int &t) const; 31 bool operator < (const wkint &t) const; 32 bool operator > (const wkint &t) const; 33 bool operator == (const wkint &t) const; 34 bool operator != (const wkint &t) const; 35 }; 36 37 wkint::wkint() { 38 len = 1; 39 memset(a, 0, sizeof(a)); 40 } 41 wkint::wkint(int t) { 42 len = 1; 43 a[1] = t; 44 } 45 void wkint::read() { 46 string tmp; 47 cin >> tmp; 48 int lenT = tmp.length(); 49 len = (lenT + 7) / 8; 50 int ptr = len, now = 0; 51 for (int i = 0; i < lenT; i ++) { 52 now *= 10; now += (int)(tmp[i] - '0'); 53 if (!((lenT - i - 1) % 8)) { 54 a[ptr] = now; 55 now = 0; 56 ptr --; 57 } 58 } 59 } 60 void wkint::print() { 61 printf(ll, a[len]); 62 for (int i = len - 1; i >= 1; i --) { 63 int ws = (int)log10((long double)(a[i] + 1)) + 1; 64 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 65 printf(ll, a[i]); 66 } 67 printf("\n"); 68 } 69 wkint wkint::operator + (const wkint &t) const { 70 wkint res; 71 int maxlen = max(t.len, len); 72 for (int i = 1; i <= maxlen; i ++) { 73 res.a[i] += a[i] + t.a[i]; 74 if (res.a[i] >= 100000000) { 75 res.a[i + 1] += res.a[i] / 100000000; 76 res.a[i] %= 100000000; 77 } 78 } 79 if (res.a[maxlen + 1]) maxlen ++; 80 res.len = maxlen; 81 return res; 82 } 83 wkint wkint::operator - (const wkint &t) const { 84 wkint res; 85 int maxlen = max(t.len, len); 86 for (int i = 1; i <= maxlen; i ++) { 87 res.a[i] += a[i] - t.a[i]; 88 if (res.a[i] < 0) { 89 res.a[i + 1] -= 1; 90 res.a[i] += 100000000; 91 } 92 } 93 while (!res.a[maxlen]) maxlen --; 94 res.len = maxlen; 95 return res; 96 } 97 wkint wkint::operator * (const wkint &t) const { 98 wkint res; 99 int maxlen = t.len + len - 1; 100 for (int i = 1; i <= len; i ++) 101 for (int j = 1; j <= t.len; j ++) { 102 res.a[i + j - 1] += a[i] * t.a[j]; 103 } 104 for (int i = 1; i <= maxlen; i ++) 105 if (res.a[i] > 100000000) { 106 res.a[i + 1] += res.a[i] / 100000000; 107 res.a[i] %= 100000000; 108 } 109 if (res.a[maxlen + 1]) maxlen ++; 110 res.len = maxlen; 111 return res; 112 } 113 wkint wkint::operator * (const int &t) const { 114 wkint res; 115 res.len = len; 116 for (int i = 1; i <= len; i ++) { 117 res.a[i] += a[i] * t; 118 if (res.a[i] > 100000000) { 119 res.a[i + 1] += res.a[i] / 100000000; 120 res.a[i] %= 100000000; 121 } 122 } 123 if (res.a[res.len + 1]) res.len ++; 124 return res; 125 } 126 wkint wkint::operator ^ (const int &t) const { 127 wkint res = wkint(1), tmp; 128 int now = t; 129 memcpy(tmp.a, a, sizeof(a)); 130 tmp.len = len; 131 while (now) { 132 if (now & 1) res = res * tmp; 133 tmp = tmp * tmp; 134 now >>= 1; 135 } 136 return res; 137 } 138 wkint wkint::operator / (const int &t) const { 139 wkint res; 140 long long now = 0; 141 res.len = len; 142 for (int i = len; i >= 1; i --) { 143 now *= 100000000, now += a[i]; 144 if (now < t) { 145 res.a[i] = 0; 146 } else { 147 res.a[i] = now / t; 148 now %= t; 149 } 150 } 151 while (!res.a[res.len]) res.len --; 152 return res; 153 } 154 int wkint::operator % (const int &t) const { 155 long long now = 0; 156 for (int i = len; i >= 1; i --) { 157 now *= 100000000, now += a[i]; 158 now %= t; 159 } 160 return (int)now; 161 } 162 bool wkint::operator < (const wkint &t) const { 163 if (len < t.len) return true; 164 if (len > t.len) return false; 165 for (int i = len; i >= 1; i --) 166 if (a[i] < t.a[i]) { 167 return true; 168 } else if (a[i] > t.a[i]) { 169 return false; 170 } 171 return false; 172 } 173 bool wkint::operator > (const wkint &t) const { 174 if (len > t.len) return true; 175 if (len < t.len) return false; 176 for (int i = len; i >= 1; i --) 177 if (a[i] > t.a[i]) { 178 return true; 179 } else if (a[i] < t.a[i]) { 180 return false; 181 } 182 return false; 183 } 184 bool wkint::operator == (const wkint &t) const { 185 if (t.len != len) return false; 186 for (int i = 1; i <= len; i ++) 187 if (a[i] != t.a[i]) { 188 return false; 189 } 190 return true; 191 } 192 bool wkint::operator != (const wkint &t) const { 193 if (t.len != len) return true; 194 for (int i = 1; i <= len; i ++) 195 if (a[i] != t.a[i]) { 196 return true; 197 } 198 return false; 199 } 200 201 int n; 202 char s[210]; 203 int now=-1; 204 wkint ans; 205 wkint bit[60]; 206 207 void dfs(int d) 208 { 209 now++; 210 if (s[now] == '1') 211 ans=ans-bit[d]; 212 if (s[now] == '2') 213 for (int i=1;i<=4;i++) 214 dfs(d-1); 215 } 216 217 int main() 218 { 219 bit[0]=1; 220 for (int i=1;i<=50;i++) 221 bit[i]=bit[i-1]*4; 222 scanf("%d%s",&n,s); 223 ans=bit[n]; 224 dfs(n); 225 ans.print(); 226 return 0; 227 }
bzoj1976
很不错的网络流,考虑割集的意义
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 64100 8 #define maxm 1250000 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,flow; 14 edge *next,*part; 15 }e[maxm<<1],*head[maxn]; 16 17 int n,ne=0; 18 int s,t; 19 int q[maxn],d[maxn]; 20 char map[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 d[p->to]=d[x]+1; 51 q[++cls]=p->to; 52 } 53 } 54 return ~d[t]; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 inline int pos(int x,int y,int z) 84 { 85 return (x-1)*n*n+(y-1)*n+z; 86 } 87 88 int main() 89 { 90 scanf("%d",&n); 91 for (int i=1;i<=n;i++) 92 for (int j=1;j<=n;j++) 93 for (int k=1;k<=n;k++) 94 { 95 char ch; 96 while (ch=getchar(),ch != '?' && ch != 'P' && ch != 'N'); 97 map[pos(i,j,k)]=ch; 98 } 99 s=0,t=n*n*n+1; 100 int sum=0; 101 for (int i=1;i<=n;i++) 102 for (int j=1;j<=n;j++) 103 for (int k=1;k<=n;k++) 104 { 105 int cnt=0; 106 if (i != 1) 107 cnt++; 108 if (i != n) 109 cnt++; 110 if (j != 1) 111 cnt++; 112 if (j != n) 113 cnt++; 114 if (k != 1) 115 cnt++; 116 if (k != n) 117 cnt++; 118 sum+=cnt; 119 if ((i+j+k)&1) 120 { 121 add_edge(s,pos(i,j,k),cnt); 122 if (map[pos(i,j,k)] == 'P') 123 add_edge(s,pos(i,j,k),inf); 124 if (map[pos(i,j,k)] == 'N') 125 add_edge(pos(i,j,k),t,inf); 126 if (i != 1) 127 add_edge(pos(i,j,k),pos(i-1,j,k),2); 128 if (i != n) 129 add_edge(pos(i,j,k),pos(i+1,j,k),2); 130 if (j != 1) 131 add_edge(pos(i,j,k),pos(i,j-1,k),2); 132 if (j != n) 133 add_edge(pos(i,j,k),pos(i,j+1,k),2); 134 if (k != 1) 135 add_edge(pos(i,j,k),pos(i,j,k-1),2); 136 if (k != n) 137 add_edge(pos(i,j,k),pos(i,j,k+1),2); 138 } 139 else 140 { 141 add_edge(pos(i,j,k),t,cnt); 142 if (map[pos(i,j,k)] == 'P') 143 add_edge(pos(i,j,k),t,inf); 144 if (map[pos(i,j,k)] == 'N') 145 add_edge(s,pos(i,j,k),inf); 146 } 147 } 148 printf("%d\n",sum-dinic()); 149 return 0; 150 }
bzoj1977
mst后倍增预处理,然后每条边带进去验证,我的代码写得奇丑无比。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 150010 7 #define maxm 800010 8 #define inf 0x3f3f3f3f3f3f3fLL 9 10 #ifdef unix 11 #define LL "%lld" 12 #else 13 #define LL "%I64d" 14 #endif 15 16 struct xxx 17 { 18 int from,to,dist; 19 bool operator < (const xxx a) const 20 { 21 return dist < a.dist; 22 } 23 }ed[maxm]; 24 25 struct edge 26 { 27 int to,dist; 28 edge *next; 29 }e[maxm],*head[maxn]; 30 31 struct path 32 { 33 int max,sec,pos; 34 }f[maxn][20]; 35 36 int ne=0; 37 int n,m; 38 int fa[maxn],r[maxn]; 39 int q[maxn],d[maxn]; 40 int bit[50]; 41 bool flag[maxn],vis[maxn]; 42 43 inline void add_edge(int from,int to,int dist) 44 { 45 e[ne].to=to; 46 e[ne].dist=dist; 47 e[ne].next=head[from]; 48 head[from]=&e[ne++]; 49 } 50 51 int find(int x) 52 { 53 if (fa[x] == x) 54 return x; 55 return fa[x]=find(fa[x]); 56 } 57 58 inline void _union(int a,int b) 59 { 60 if (r[a] <= r[b]) 61 { 62 fa[a]=b; 63 r[b]+=r[a]; 64 } 65 else 66 { 67 fa[b]=a; 68 r[a]+=r[b]; 69 } 70 } 71 72 inline void read(int &x) 73 { 74 char ch; 75 while (ch=getchar(),ch > '9' || ch < '0'); 76 x=ch-'0'; 77 while (ch=getchar(),ch <= '9' && ch >= '0') 78 x=(x<<3)+x+x+ch-'0'; 79 } 80 81 inline void bfs() 82 { 83 int op=0,cls=1; 84 q[1]=1; 85 vis[1]=1; 86 while (op != cls) 87 { 88 int x=q[++op]; 89 for (edge *p=head[x];p;p=p->next) 90 if (!vis[p->to]) 91 { 92 f[p->to][0].pos=x; 93 f[p->to][0].max=p->dist; 94 vis[p->to]=1; 95 q[++cls]=p->to; 96 d[p->to]=d[x]+1; 97 } 98 } 99 } 100 101 inline void lca_pre() 102 { 103 for (int i=1;i<=19;i++) 104 for (int j=1;j<=n;j++) 105 { 106 f[j][i].pos=f[f[j][i-1].pos][i-1].pos; 107 f[j][i].max=max(f[j][i-1].max,f[f[j][i-1].pos][i-1].max); 108 if (f[j][i-1].max == f[f[j][i-1].pos][i-1].max) 109 f[j][i].sec=max(f[j][i-1].sec,f[f[j][i-1].pos][i-1].sec); 110 else 111 f[j][i].sec=min(f[j][i-1].max,f[f[j][i-1].pos][i-1].max); 112 } 113 } 114 115 int main() 116 { 117 bit[0]=1; 118 for (int i=1;i<=30;i++) 119 bit[i]=bit[i-1]+bit[i-1]; 120 read(n); 121 read(m); 122 for (int i=1;i<=m;i++) 123 { 124 read(ed[i].from); 125 read(ed[i].to); 126 read(ed[i].dist); 127 } 128 sort(ed+1,ed+m+1); 129 for (int i=1;i<=n;i++) 130 { 131 fa[i]=i; 132 r[i]=1; 133 } 134 long long len=0; 135 for (int i=1;i<=m;i++) 136 { 137 int x=find(ed[i].from); 138 int y=find(ed[i].to); 139 if (x != y) 140 { 141 _union(x,y); 142 add_edge(ed[i].from,ed[i].to,ed[i].dist); 143 add_edge(ed[i].to,ed[i].from,ed[i].dist); 144 len+=ed[i].dist; 145 flag[i]=1; 146 } 147 } 148 d[1]=0; 149 bfs(); 150 lca_pre(); 151 long long ans=inf; 152 for (int i=1;i<=m;i++) 153 if (!flag[i]) 154 { 155 int x=ed[i].from,y=ed[i].to,now=ed[i].dist; 156 if (d[x] < d[y]) 157 x^=y^=x^=y; 158 int _max=0,_sec=0; 159 for (int j=19;j>=0;j--) 160 if (d[x]-d[y] >= bit[j]) 161 { 162 if (f[x][j].max > _max) 163 { 164 _sec=_max; 165 _max=f[x][j].max; 166 } 167 else 168 { 169 if (f[x][j].max > _sec) 170 _sec=f[x][j].max; 171 else 172 if (f[x][j].sec > _sec) 173 _sec=f[x][j].sec; 174 } 175 x=f[x][j].pos; 176 } 177 if (x != y) 178 { 179 for (int j=19;j>=0;j--) 180 if (f[x][j].pos != f[y][j].pos) 181 { 182 if (f[x][j].max > _max) 183 { 184 _sec=_max; 185 _max=f[x][j].max; 186 } 187 else 188 { 189 if (f[x][j].max > _sec) 190 _sec=f[x][j].max; 191 else 192 if (f[x][j].sec > _sec) 193 _sec=f[x][j].sec; 194 } 195 x=f[x][j].pos; 196 if (f[y][j].max > _max) 197 { 198 _sec=_max; 199 _max=f[y][j].max; 200 } 201 else 202 { 203 if (f[y][j].max > _sec) 204 _sec=f[y][j].max; 205 else 206 if (f[y][j].sec > _sec) 207 _sec=f[y][j].sec; 208 } 209 y=f[y][j].pos; 210 } 211 if (f[x][0].max > _max) 212 { 213 _sec=_max; 214 _max=f[x][0].max; 215 } 216 else 217 { 218 if (f[x][0].max > _sec) 219 _sec=f[x][0].max; 220 } 221 if (f[y][0].max > _max) 222 { 223 _sec=_max; 224 _max=f[y][0].max; 225 } 226 else 227 { 228 if (f[y][0].max > _sec) 229 _sec=f[y][0].max; 230 } 231 } 232 if (now > _max) 233 ans=min(ans,len+now-_max); 234 else 235 ans=min(ans,len+now-_sec); 236 } 237 printf(LL,ans); 238 return 0; 239 }
bzoj1978
边读边枚举约数即可
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 int now[maxn],f[maxn]; 6 7 inline int max(int a,int b) 8 { 9 return a > b ? a : b; 10 } 11 12 int main() 13 { 14 int n,l,ans=0; 15 scanf("%d%d",&n,&l); 16 for (int i=1;i<=n;i++) 17 { 18 int x; 19 scanf("%d",&x); 20 now[0]=0; 21 for (int j=1;j*j<=x;j++) 22 if (x%j == 0) 23 { 24 now[++now[0]]=j; 25 now[++now[0]]=x/j; 26 } 27 int _max=0; 28 for (int j=1;j<=now[0];j++) 29 if (now[j] >= l) 30 _max=max(_max,f[now[j]]+1); 31 ans=max(ans,_max); 32 for (int j=1;j<=now[0];j++) 33 f[now[j]]=max(f[now[j]],_max); 34 } 35 printf("%d\n",ans); 36 return 0; 37 }
bzoj1996
区间DP,f[l][r][2]表示这个区间最后加的是左边还是右边的方案数
1 #include <cstdio> 2 3 #define maxn 1010 4 #define mod 19650827 5 6 int f[maxn][maxn][2]; 7 int a[maxn]; 8 9 inline void inc(int &a,int b) 10 { 11 a+=b; 12 while (a >= mod) 13 a-=mod; 14 } 15 16 int main() 17 { 18 int n; 19 scanf("%d",&n); 20 for (int i=1;i<=n;i++) 21 { 22 scanf("%d",&a[i]); 23 f[i][i][0]=1; 24 } 25 for (int i=1;i<n;i++) 26 for (int j=1;i+j<=n;j++) 27 { 28 int l=j,r=i+j; 29 if (a[r] > a[l]) 30 inc(f[l][r][1],f[l][r-1][0]); 31 if (a[r] > a[r-1]) 32 inc(f[l][r][1],f[l][r-1][1]); 33 if (a[l] < a[l+1]) 34 inc(f[l][r][0],f[l+1][r][0]); 35 if (a[l] < a[r]) 36 inc(f[l][r][0],f[l+1][r][1]); 37 } 38 int ans=f[1][n][0]+f[1][n][1]; 39 while (ans >= mod) 40 ans-=mod; 41 printf("%d\n",ans); 42 return 0; 43 }
bzoj2002
水水的lct,据说可以用分块做
1 #include <cstdio> 2 3 #define maxn 200010 4 5 struct Node 6 { 7 int size; 8 Node *s[2],*par; 9 bool rt; 10 }t[maxn],null; 11 12 inline void _update(Node* now) 13 { 14 now->size=now->s[0]->size+now->s[1]->size+1; 15 } 16 17 inline void _rot(Node* now,int l) 18 { 19 int r=!l; 20 Node* p=now->par; 21 Node* s=now->s[l]; 22 (now->s[l]=s->s[r])->par=now; 23 (s->s[r]=now)->par=s; 24 s->par=p; 25 if (now->rt) 26 { 27 now->rt=0; 28 s->rt=1; 29 } 30 else 31 p->s[now == p->s[1]]=s; 32 _update(now); 33 _update(s); 34 } 35 36 inline void _splay(Node* now) 37 { 38 while (!now->rt) 39 { 40 Node* p=now->par; 41 Node* g=p->par; 42 bool dp=now == p->s[1]; 43 bool dg=p == g->s[1]; 44 if (p->rt) 45 { 46 _rot(p,dp); 47 return; 48 } 49 if (dp == dg) 50 { 51 _rot(g,dg); 52 _rot(p,dp); 53 } 54 else 55 { 56 _rot(p,dp); 57 _rot(g,dg); 58 } 59 } 60 } 61 62 inline void access(Node* now) 63 { 64 Node* p=now; 65 Node* q=&null; 66 do 67 { 68 _splay(p); 69 if (p->s[1] != &null) 70 p->s[1]->rt=1; 71 p->s[1]=q; 72 if (q != &null) 73 { 74 q->rt=0; 75 q->par=p; 76 } 77 _update(p); 78 q=p; 79 p=p->par; 80 } 81 while (p != &null); 82 } 83 84 inline void cut(Node* now) 85 { 86 access(now); 87 _splay(now); 88 now->s[0]->rt=1; 89 now->s[0]->par=&null; 90 now->s[0]=&null; 91 _update(now); 92 } 93 94 inline void link(Node* now,Node* par) 95 { 96 access(now); 97 now->par=par; 98 } 99 100 int main() 101 { 102 null.s[0]=null.s[1]=null.par=&null; 103 null.size=0; 104 null.rt=1; 105 int n; 106 scanf("%d",&n); 107 t[n+1].par=t[n+1].s[0]=t[n+1].s[1]=&null; 108 t[n+1].rt=1; 109 for (int i=1;i<=n;i++) 110 { 111 int x; 112 scanf("%d",&x); 113 t[i].s[0]=t[i].s[1]=t[i].par=&null; 114 t[i].rt=1; 115 t[i].size=1; 116 if (i+x > n) 117 t[i].par=&t[n+1]; 118 else 119 t[i].par=&t[i+x]; 120 } 121 int _; 122 scanf("%d",&_); 123 while (_--) 124 { 125 int x,y,z; 126 scanf("%d",&x); 127 if (x == 1) 128 { 129 scanf("%d",&y); 130 y++; 131 access(&t[y]); 132 _splay(&t[y]); 133 printf("%d\n",t[y].s[0]->size); 134 } 135 else 136 { 137 scanf("%d%d",&y,&z); 138 y++; 139 cut(&t[y]); 140 if (y+z <= n) 141 link(&t[y],&t[y+z]); 142 else 143 link(&t[y],&t[n+1]); 144 } 145 } 146 return 0; 147 }
bzoj2005
算gcd要T,就枚举gcd吧
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 long long f[maxn]; 9 10 int main() 11 { 12 long long n,m,sum=0; 13 scanf("%lld %lld",&n,&m); 14 for (long long i=min(n,m);i;i--) 15 { 16 f[i]=(n/i)*(m/i); 17 for (long long j=2;i*j <= min(n,m);j++) 18 f[i]-=f[i*j]; 19 sum+=(2*i-1)*f[i]; 20 } 21 printf("%lld",sum); 22 return 0; 23 }
bzoj2006
主席树+堆
1 #include <cstdio> 2 #include <algorithm> 3 #include <queue> 4 5 using namespace std; 6 7 #define maxn 500010 8 #define inf 0x3f3f3f3f3f3f3f3fLL 9 10 struct Node 11 { 12 long long size; 13 Node *s[2]; 14 }t[maxn*20],*root[maxn],null; 15 16 struct xxx 17 { 18 long long pos,val; 19 friend bool operator < (const xxx a,const xxx b) 20 { 21 return a.val < b.val; 22 } 23 }; 24 25 priority_queue <xxx> q; 26 27 long long ne=0; 28 long long a[maxn],b[maxn],now[maxn]; 29 30 Node* update(Node* pre,long long val,long long l,long long r) 31 { 32 Node* now=&t[ne++]; 33 now->s[0]=pre->s[0]; 34 now->s[1]=pre->s[1]; 35 now->size=pre->size+1; 36 if (l == r) 37 return now; 38 long long mid=(l+r)>>1; 39 if (val <= mid) 40 now->s[0]=update(pre->s[0],val,l,mid); 41 else 42 now->s[1]=update(pre->s[1],val,mid+1,r); 43 return now; 44 } 45 46 inline long long query(Node* L,Node* R,long long l,long long r,long long k) 47 { 48 if (R->size-L->size < k) 49 return 0; 50 while (1) 51 { 52 if (l == r) 53 return l; 54 long long mid=(l+r)>>1,del=R->s[1]->size-L->s[1]->size; 55 if (k <= del) 56 { 57 l=mid+1; 58 L=L->s[1]; 59 R=R->s[1]; 60 } 61 else 62 { 63 r=mid; 64 k-=del; 65 L=L->s[0]; 66 R=R->s[0]; 67 } 68 } 69 } 70 71 int main() 72 { 73 null.s[0]=null.s[1]=&null; 74 null.size=0; 75 long long n,k,l,r; 76 scanf("%lld%lld%lld%lld",&n,&k,&l,&r); 77 for (long long i=1;i<=n;i++) 78 { 79 scanf("%lld",&a[i]); 80 a[i]+=a[i-1]; 81 b[i]=a[i]; 82 } 83 sort(b+1,b+n+1); 84 long long size=unique(b+1,b+n+1)-b-1; 85 for (long long i=1;i<=n;i++) 86 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 87 a[0]=size+1; 88 b[size+1]=0; 89 root[0]=&null; 90 for (long long i=1;i<=n;i++) 91 root[i]=update(root[i-1],a[i],1,size); 92 for (long long i=1;i<=n-l+1;i++) 93 { 94 xxx p; 95 p.pos=i; 96 p.val=b[query(root[i+l-2],root[min(i+r-1,n)],1,size,1)]-b[a[i-1]]; 97 q.push(p); 98 now[i]=1; 99 } 100 long long ans=0; 101 for (long long i=1;i<=k;i++) 102 { 103 xxx p=q.top(); 104 q.pop(); 105 ans+=p.val; 106 now[p.pos]++; 107 int u=query(root[p.pos+l-2],root[min(p.pos+r-1,n)],1,size,now[p.pos]); 108 if (u) 109 p.val=b[u]-b[a[p.pos-1]]; 110 else 111 p.val=-inf; 112 q.push(p); 113 } 114 printf("%lld\n",ans); 115 return 0; 116 }
bzoj2007
1001的网络流让我误以为网络流比转出来的最短路要快,结果这道题网络流跑最后一个点只需要差点两分钟。。。最小割转化为最短路
1 #include <cstdio> 2 #include <cstring> 3 #include <bitset> 4 5 using namespace std; 6 7 #define maxn 280010 8 #define maxm 1200010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,dist; 14 edge *next; 15 }e[maxm],*head[maxn]; 16 17 int n,s,t; 18 int ne=0; 19 int d[maxn],q[maxn]; 20 21 bitset <maxn> flag; 22 23 inline void add_edge(int from,int to,int dist) 24 { 25 e[ne].to=to; 26 e[ne].dist=dist; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline int spfa() 32 { 33 memset(d,0x3f,sizeof(d)); 34 int op=0,cls=1; 35 q[1]=s; 36 d[s]=0; 37 flag[s]=1; 38 while (op != cls) 39 { 40 op=op == maxn-1 ? 0 : op+1; 41 int x=q[op]; 42 for (edge *p=head[x];p;p=p->next) 43 if (d[p->to] > d[x]+p->dist) 44 { 45 d[p->to]=d[x]+p->dist; 46 if (!flag[p->to]) 47 { 48 if (op != cls) 49 { 50 int now=op == maxn-1 ? 0 : op+1; 51 if (d[p->to] < d[q[now]]) 52 { 53 q[op]=p->to; 54 op=op == 0 ? maxn-1 : op-1; 55 } 56 else 57 { 58 cls=cls == maxn-1 ? 0 : cls+1; 59 q[cls]=p->to; 60 } 61 } 62 else 63 { 64 cls=cls == maxn-1 ? 0 : cls+1; 65 q[cls]=p->to; 66 } 67 flag[p->to]=1; 68 } 69 } 70 flag[x]=0; 71 } 72 return d[t]; 73 } 74 75 inline int pos(int a,int b) 76 { 77 return (a-1)*n+b; 78 } 79 80 int main() 81 { 82 scanf("%d",&n); 83 s=0; 84 t=n*n+1; 85 int x; 86 for (int i=0;i<=n;i++) 87 for (int j=1;j<=n;j++) 88 { 89 scanf("%d",&x); 90 if (!i) 91 add_edge(pos(i+1,j),t,x); 92 else 93 if (i == n) 94 add_edge(s,pos(i,j),x); 95 else 96 add_edge(pos(i+1,j),pos(i,j),x); 97 } 98 for (int i=1;i<=n;i++) 99 for (int j=0;j<=n;j++) 100 { 101 scanf("%d",&x); 102 if (!j) 103 add_edge(s,pos(i,j+1),x); 104 else 105 if (j == n) 106 add_edge(pos(i,j),t,x); 107 else 108 add_edge(pos(i,j),pos(i,j+1),x); 109 } 110 for (int i=0;i<=n;i++) 111 for (int j=1;j<=n;j++) 112 { 113 scanf("%d",&x); 114 if (!i) 115 add_edge(t,pos(i+1,j),x); 116 else 117 if (i == n) 118 add_edge(pos(i,j),s,x); 119 else 120 add_edge(pos(i,j),pos(i+1,j),x); 121 } 122 for (int i=1;i<=n;i++) 123 for (int j=0;j<=n;j++) 124 { 125 scanf("%d",&x); 126 if (!j) 127 add_edge(pos(i,j+1),s,x); 128 else 129 if (j == n) 130 add_edge(t,pos(i,j),x); 131 else 132 add_edge(pos(i,j+1),pos(i,j),x); 133 } 134 printf("%d\n",spfa()); 135 return 0; 136 }
bzoj2049
我写的第一道真正意义上的lct(弹飞绵羊那货不算。。。)据说可以用并查集,而且跑得飞快QAQ
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 10010 7 8 struct Node 9 { 10 bool rot; 11 Node *s[2],*par; 12 13 Node() 14 { 15 rot=0; 16 } 17 18 inline bool S() 19 { 20 return this == par->s[1]; 21 } 22 }t[maxn],null; 23 24 inline bool root(Node* now) 25 { 26 return now->par->s[0] != now && now->par->s[1] != now; 27 } 28 29 inline void _pushdown(Node* now) 30 { 31 if (now->rot) 32 { 33 now->rot=0; 34 now->s[0]->rot^=1; 35 now->s[1]->rot^=1; 36 swap(now->s[0],now->s[1]); 37 } 38 } 39 40 inline void _rot(Node* now) 41 { 42 Node* p=now->par; 43 if (!root(p)) 44 _pushdown(p->par); 45 _pushdown(p); 46 _pushdown(now); 47 int l=now->S(),r=!l; 48 (p->s[l]=now->s[r])->par=p; 49 if (root(p)) 50 now->par=p->par; 51 else 52 (p->par->s[p->S()]=now)->par=p->par; 53 (now->s[r]=p)->par=now; 54 } 55 56 inline void _splay(Node* now) 57 { 58 while (!root(now)) 59 { 60 if (root(now->par)) 61 { 62 _rot(now); 63 return; 64 } 65 if (now->par->S() == now->S()) 66 { 67 _rot(now->par); 68 _rot(now); 69 } 70 else 71 { 72 _rot(now); 73 _rot(now); 74 } 75 } 76 } 77 78 inline Node* access(Node* p) 79 { 80 Node* q=&null; 81 for (;p!=&null;q=p,p=p->par) 82 { 83 _splay(p); 84 _pushdown(p); 85 (p->s[1]=q)->par=p; 86 } 87 return q; 88 } 89 90 inline Node* find_root(Node* now) 91 { 92 for (_pushdown(now=access(now));now->s[0] != &null;_pushdown(now=now->s[0])); 93 return now; 94 } 95 96 inline void set_root(Node* now) 97 { 98 access(now); 99 _splay(now); 100 now->rot^=1; 101 } 102 103 inline void link(Node* p,Node* q) 104 { 105 set_root(p); 106 p->par=q; 107 } 108 109 inline void cut(Node* p,Node* q) 110 { 111 set_root(p); 112 access(q); 113 _splay(q); 114 p->par=q->s[0]=&null; 115 } 116 117 int main() 118 { 119 null.s[0]=null.s[1]=null.par=&null; 120 null.rot=0; 121 int n,m; 122 scanf("%d%d",&n,&m); 123 for (int i=1;i<=n;i++) 124 t[i].s[0]=t[i].s[1]=t[i].par=&null; 125 while (m--) 126 { 127 char s[10]; 128 int x,y; 129 scanf("%s%d%d",s,&x,&y); 130 if (s[0] == 'Q') 131 { 132 if (find_root(&t[x]) == find_root(&t[y])) 133 puts("Yes"); 134 else 135 puts("No"); 136 } 137 else 138 { 139 if (s[0] == 'C') 140 link(&t[x],&t[y]); 141 else 142 cut(&t[x],&t[y]); 143 } 144 } 145 return 0; 146 }
bzoj2063
数位DP,想象成一棵十叉树,然后就是两个叶结点往上走的问题了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 typedef pair <long long ,long long > pii; 7 8 pii f[18][200][1010]; 9 bool vis[18][200][1010]; 10 11 long long m; 12 long long bit[20]; 13 14 inline pii merge(pii x,pii y) 15 { 16 x.first+=y.first; 17 x.second=y.second; 18 return x; 19 } 20 21 pii fdp(long long d,long long sum,long long rest) 22 { 23 if (vis[d][sum][rest]) 24 return f[d][sum][rest]; 25 vis[d][sum][rest]=1; 26 if (!d) 27 { 28 if (!rest) 29 { 30 f[d][sum][rest].first=1; 31 if (sum < m) 32 f[d][sum][rest].second=m-sum; 33 else 34 f[d][sum][rest].second=0; 35 } 36 else 37 { 38 f[d][sum][rest].first=0; 39 if (rest > sum) 40 f[d][sum][rest].second=rest-sum; 41 else 42 f[d][sum][rest].second=0; 43 } 44 return f[d][sum][rest]; 45 } 46 f[d][sum][rest].first=0; 47 f[d][sum][rest].second=rest; 48 for (long long i=0;i<10;i++) 49 f[d][sum][rest]=merge(f[d][sum][rest],fdp(d-1,sum+i,f[d][sum][rest].second)); 50 return f[d][sum][rest]; 51 } 52 53 pii solve(long long n,long long m) 54 { 55 long long l=n,r=m,h=-1,suml=0,sumr=0; 56 for (long long i=18;i>=0;i--) 57 { 58 if (h < 0 && l/bit[i] != r/bit[i]) 59 h=i; 60 suml+=l/bit[i]; 61 sumr+=r/bit[i]; 62 l%=bit[i]; 63 r%=bit[i]; 64 } 65 pii ans; 66 ans.first=ans.second=0; 67 l=n,r=m; 68 ans=merge(ans,fdp(0,suml,ans.second)); 69 for (long long i=0;i<h;i++) 70 { 71 suml-=l%bit[i+1]/bit[i]; 72 for (long long j=l%bit[i+1]/bit[i]+1;j<10;j++) 73 ans=merge(ans,fdp(i,suml+j,ans.second)); 74 } 75 suml-=l%bit[h+1]/bit[h]; 76 for (long long i=l%bit[h+1]/bit[h]+1;i<r%bit[h+1]/bit[h];i++) 77 ans=merge(ans,fdp(h,suml+i,ans.second)); 78 for (long long i=h-1;i>=0;i--) 79 { 80 suml+=r%bit[i+2]/bit[i+1]; 81 for (long long j=0;j<r%bit[i+1]/bit[i];j++) 82 ans=merge(ans,fdp(i,suml+j,ans.second)); 83 } 84 ans=merge(ans,fdp(0,suml+r%10,ans.second)); 85 return ans; 86 } 87 88 int main() 89 { 90 bit[0]=1; 91 for (long long i=1;i<=18;i++) 92 bit[i]=bit[i-1]*10; 93 bool flag=0; 94 long long l,r; 95 scanf("%lld%lld%lld",&l,&r,&m); 96 if (r == 1000000000000000000LL) 97 { 98 flag=1; 99 r--; 100 } 101 if (l == r) 102 { 103 long long now=0; 104 while (l) 105 { 106 now+=l%10; 107 l/=10; 108 } 109 printf("%lld\n",now); 110 return 0; 111 } 112 pii ans=solve(l,r); 113 if (flag) 114 { 115 if (!ans.second) 116 { 117 ans.first++; 118 ans.second=m; 119 } 120 ans.second--; 121 } 122 if (ans.second) 123 ans.first--; 124 printf("%lld\n",ans.first); 125 return 0; 126 }
bzoj2109
DFS之后贪心
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 2010 8 #define maxm 10010 9 10 struct edge 11 { 12 int to; 13 edge *next; 14 }e[maxm],*head[maxn]; 15 16 int ne=0; 17 int cnt=0; 18 int q[maxn],ans[maxn],in[maxn]; 19 pair <int,int> a[maxn]; 20 bool check[maxn][maxn]; 21 bool flag[maxn]; 22 23 inline void add_edge(int from,int to) 24 { 25 e[ne].to=to; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 void dfs(int x) 31 { 32 flag[x]=1; 33 for (edge *p=head[x];p;p=p->next) 34 if (!flag[p->to]) 35 dfs(p->to); 36 q[++cnt]=x; 37 } 38 39 void dfs(int now,int x) 40 { 41 flag[x]=1; 42 check[now][x]=1; 43 for (edge *p=head[x];p;p=p->next) 44 if (!flag[p->to]) 45 dfs(now,p->to); 46 } 47 48 int main() 49 { 50 int n,m; 51 scanf("%d%d",&n,&m); 52 int x,y; 53 for (int i=1;i<=n;i++) 54 { 55 scanf("%d",&a[i].first); 56 a[i].second=i; 57 } 58 for (int i=1;i<=m;i++) 59 { 60 scanf("%d%d",&x,&y); 61 add_edge(y,x); 62 } 63 for (int i=1;i<=n;i++) 64 if (!flag[i]) 65 dfs(i); 66 for (int i=n;i;i--) 67 { 68 int x=q[i]; 69 for (edge *p=head[x];p;p=p->next) 70 a[p->to].first=min(a[p->to].first,a[x].first-1); 71 } 72 sort(a+1,a+n+1); 73 for (int i=1;i<=n;i++) 74 { 75 memset(flag,0,sizeof(flag)); 76 dfs(i,i); 77 } 78 for (int i=1;i<=n;i++) 79 { 80 int now=n; 81 for (int j=n;j;j--) 82 if (!check[i][a[j].second] && a[j].first >= now) 83 now--; 84 else 85 if (a[j].first < now) 86 break; 87 printf("%d ",now); 88 } 89 return 0; 90 }
bzoj2111
相当于是一个堆,怎么递推乱搞一下就可以了
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 #ifdef unix 6 #define LL "%lld" 7 #else 8 #define LL "%I64d" 9 #endif 10 11 long long n,p; 12 long long size[maxn],f[maxn]; 13 14 inline long long power(long long a,long long b) 15 { 16 long long ans=1,wk=a; 17 while (b) 18 { 19 if (b&1) 20 (ans*=wk)%=p; 21 (wk*=wk)%=p; 22 b>>=1; 23 } 24 return ans; 25 } 26 27 inline long long C(long long a,long long b) 28 { 29 long long fenzi=1,fenmu=1; 30 for (long long i=1;i<=b;i++) 31 { 32 (fenzi*=(a-i+1))%=p; 33 (fenmu*=i)%=p; 34 } 35 long long ans=(fenzi*power(fenmu,p-2))%p; 36 return ans; 37 } 38 39 int main() 40 { 41 scanf(LL LL,&n,&p); 42 for (long long i=n;i;i--) 43 { 44 if (i*2 > n) 45 size[i]=1; 46 else 47 size[i]=size[2*i]+size[2*i+1]+1; 48 } 49 for (long long i=n;i;i--) 50 { 51 if (i*2+1 > n) 52 f[i]=1; 53 else 54 f[i]=((f[i*2]*f[i*2+1])%p*C(size[i]-1,size[2*i]))%p; 55 } 56 printf(LL "\n",f[1]); 57 return 0; 58 }
bzoj2120
set+树状数组套主席树,维护每一个位置的颜色在下一次出现的位置,统计一段区间内大于某个数的数的个数
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <set> 5 6 using namespace std; 7 8 #define maxn 20010 9 #define inf 0x3f3f3f3f 10 11 set <int> col[maxn]; 12 set <int>::iterator it; 13 14 struct Node 15 { 16 int size; 17 Node* s[2]; 18 Node() 19 { 20 size=0; 21 } 22 }t[maxn*250],*root[maxn],null,*L[100],*R[100]; 23 24 int lsize,rsize; 25 int ne=0,n,m,size; 26 int a[maxn],b[maxn]; 27 char ch[maxn][2]; 28 int q[maxn][2]; 29 int now[maxn],prev[maxn],next[maxn]; 30 31 inline void read(int& x) 32 { 33 char ch; 34 while (ch=getchar(),ch > '9' || ch < '0'); 35 x=ch-'0'; 36 while (ch=getchar(),ch <= '9' && ch >= '0') 37 x=(x<<3)+x+x+ch-'0'; 38 } 39 40 inline void update(Node* now,int val,int add) 41 { 42 int l=1,r=n+1; 43 while (1) 44 { 45 now->size+=add; 46 if (l == r) 47 return; 48 int mid=(l+r)>>1; 49 if (val <= mid) 50 { 51 if (now->s[0] == &null) 52 { 53 now->s[0]=&t[ne++]; 54 now->s[0]->s[0]=now->s[0]->s[1]=&null; 55 } 56 now=now->s[0]; 57 r=mid; 58 } 59 else 60 { 61 if (now->s[1] == &null) 62 { 63 now->s[1]=&t[ne++]; 64 now->s[1]->s[0]=now->s[1]->s[1]=&null; 65 } 66 now=now->s[1]; 67 l=mid+1; 68 } 69 } 70 } 71 72 inline void bit_update(int pos,int val,int add) 73 { 74 for (;pos<=n;pos+=pos & -pos) 75 update(root[pos],val,add); 76 } 77 78 inline int query(int l,int r) 79 { 80 lsize=rsize=0; 81 int x=l,y=r,ans=0,k=r; 82 for (;x;x-=x & -x) 83 L[++lsize]=root[x]; 84 for (;y;y-=y & -y) 85 R[++rsize]=root[y]; 86 l=1,r=n+1; 87 while (1) 88 { 89 if (l == r) 90 { 91 for (int i=1;i<=lsize;i++) 92 ans-=L[i]->size; 93 for (int i=1;i<=rsize;i++) 94 ans+=R[i]->size; 95 break; 96 } 97 int mid=(l+r)>>1; 98 if (k >= mid) 99 { 100 for (int i=1;i<=lsize;i++) 101 L[i]=L[i]->s[1]; 102 for (int i=1;i<=rsize;i++) 103 R[i]=R[i]->s[1]; 104 l=mid+1; 105 } 106 else 107 { 108 for (int i=1;i<=lsize;i++) 109 ans-=L[i]->s[1]->size; 110 for (int i=1;i<=rsize;i++) 111 ans+=R[i]->s[1]->size; 112 for (int i=1;i<=lsize;i++) 113 L[i]=L[i]->s[0]; 114 for (int i=1;i<=rsize;i++) 115 R[i]=R[i]->s[0]; 116 r=mid; 117 } 118 } 119 return ans; 120 } 121 122 int main() 123 { 124 // freopen("1.in","r",stdin); 125 // freopen("1.out","w",stdout); 126 read(n); 127 read(m); 128 for (int i=1;i<=n;i++) 129 { 130 read(a[i]); 131 b[i]=a[i]; 132 } 133 size=n; 134 for (int i=1;i<=m;i++) 135 { 136 scanf("%s",ch[i]); 137 read(q[i][0]); 138 read(q[i][1]); 139 if (ch[i][0] == 'R') 140 b[++size]=q[i][1]; 141 } 142 sort(b+1,b+size+1); 143 size=unique(b+1,b+size+1)-b-1; 144 for (int i=1;i<=n;i++) 145 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 146 for (int i=1;i<=n;i++) 147 { 148 next[i]=n+1; 149 if (!now[a[i]]) 150 now[a[i]]=i; 151 else 152 { 153 next[now[a[i]]]=i; 154 prev[i]=now[a[i]]; 155 now[a[i]]=i; 156 } 157 col[a[i]].insert(i); 158 } 159 null.s[0]=null.s[1]=&null; 160 root[0]=&null; 161 for (int i=1;i<=n;i++) 162 { 163 root[i]=&t[ne++]; 164 root[i]->s[0]=root[i]->s[1]=&null; 165 } 166 for (int i=1;i<=n;i++) 167 bit_update(i,next[i],1); 168 for (int i=1;i<=m;i++) 169 if (ch[i][0] == 'Q') 170 printf("%d\n",query(q[i][0]-1,q[i][1])); 171 else 172 { 173 int pos=q[i][0],val=lower_bound(b+1,b+size+1,q[i][1])-b; 174 if (prev[pos]) 175 { 176 bit_update(prev[pos],pos,-1); 177 next[prev[pos]]=next[pos]; 178 bit_update(prev[pos],next[pos],1); 179 } 180 if (next[pos] != n+1) 181 prev[next[pos]]=prev[pos]; 182 col[a[pos]].erase(pos); 183 a[pos]=val; 184 it=col[val].upper_bound(pos); 185 bit_update(pos,next[pos],-1); 186 if (*it > pos) 187 { 188 next[pos]=*it; 189 prev[*it]=pos; 190 } 191 else 192 next[pos]=n+1; 193 bit_update(pos,next[pos],1); 194 if (it != col[val].begin()) 195 { 196 it--; 197 bit_update(*it,next[*it],-1); 198 next[*it]=pos; 199 prev[pos]=*it; 200 bit_update(*it,next[*it],1); 201 } 202 else 203 prev[pos]=0; 204 col[val].insert(pos); 205 } 206 return 0; 207 }
bzoj2127
很难想(对我来说)的最小割
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 10010 8 #define maxm 1000010 9 #define inf 1e+9 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 q[++cls]=p->to; 51 d[p->to]=d[x]+1; 52 } 53 } 54 return ~d[t]; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (out == now_flow) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int pos[110][110]; 84 85 int main() 86 { 87 int n,m; 88 scanf("%d%d",&n,&m); 89 for (int i=1;i<=n;i++) 90 for (int j=1;j<=m;j++) 91 pos[i][j]=(i-1)*m+j; 92 int cnt=0; 93 for (int i=1;i<=n;i++) 94 for (int j=1;j<=m;j++) 95 { 96 int x; 97 scanf("%d",&x); 98 x<<=1; 99 cnt+=x; 100 add_edge(s,pos[i][j],x); 101 } 102 for (int i=1;i<=n;i++) 103 for (int j=1;j<=m;j++) 104 { 105 int x; 106 scanf("%d",&x); 107 x<<=1; 108 cnt+=x; 109 add_edge(pos[i][j],t,x); 110 } 111 for (int i=1;i<n;i++) 112 for (int j=1;j<=m;j++) 113 { 114 int x; 115 scanf("%d",&x); 116 x<<=1; 117 cnt+=x; 118 x>>=1; 119 add_edge(pos[i][j],pos[i+1][j],x); 120 add_edge(pos[i+1][j],pos[i][j],x); 121 add_edge(s,pos[i][j],x); 122 add_edge(s,pos[i+1][j],x); 123 } 124 for (int i=1;i<n;i++) 125 for (int j=1;j<=m;j++) 126 { 127 int x; 128 scanf("%d",&x); 129 x<<=1; 130 cnt+=x; 131 x>>=1; 132 add_edge(pos[i][j],pos[i+1][j],x); 133 add_edge(pos[i+1][j],pos[i][j],x); 134 add_edge(pos[i][j],t,x); 135 add_edge(pos[i+1][j],t,x); 136 } 137 for (int i=1;i<=n;i++) 138 for (int j=1;j<m;j++) 139 { 140 int x; 141 scanf("%d",&x); 142 x<<=1; 143 cnt+=x; 144 x>>=1; 145 add_edge(pos[i][j],pos[i][j+1],x); 146 add_edge(pos[i][j+1],pos[i][j],x); 147 add_edge(s,pos[i][j],x); 148 add_edge(s,pos[i][j+1],x); 149 } 150 for (int i=1;i<=n;i++) 151 for (int j=1;j<m;j++) 152 { 153 int x; 154 scanf("%d",&x); 155 x<<=1; 156 cnt+=x; 157 x>>=1; 158 add_edge(pos[i][j],pos[i][j+1],x); 159 add_edge(pos[i][j+1],pos[i][j],x); 160 add_edge(pos[i][j],t,x); 161 add_edge(pos[i][j+1],t,x); 162 } 163 int ans=cnt-dinic(); 164 printf("%d\n",ans>>1); 165 return 0; 166 }
bzoj2128
二维树状数组套主席树的常数太大了。。。于是就如题目名称所示,我cheat了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 260 7 8 struct Node 9 { 10 int size; 11 Node *s[2]; 12 }t[20000010],*root[maxn][maxn],*L[500],*R[500],*l[500],*r[500],null; 13 14 int lsize,rsize; 15 int size=0; 16 int ne=0; 17 int n,m; 18 int a[3010],b[3010],c[3010]; 19 int v[maxn][maxn]; 20 int q[100010][7]; 21 int f[maxn][maxn]; 22 int san[maxn*maxn*5]; 23 24 inline Node* new_Node() 25 { 26 Node* now=&t[ne++]; 27 now->s[0]=now->s[1]=&null; 28 now->size=0; 29 return now; 30 } 31 32 inline void update(Node* now,int val) 33 { 34 int l=1,r=size; 35 while (1) 36 { 37 now->size++; 38 if (l == r) 39 return; 40 int mid=(l+r)>>1; 41 if (val <= mid) 42 { 43 if (now->s[0] == &null) 44 now->s[0]=new_Node(); 45 now=now->s[0]; 46 r=mid; 47 } 48 else 49 { 50 if (now->s[1] == &null) 51 now->s[1]=new_Node(); 52 now=now->s[1]; 53 l=mid+1; 54 } 55 } 56 } 57 58 inline void bit_update(int x,int y,int val) 59 { 60 for (int i=x;i<=n;i+=i&-i) 61 for (int j=y;j<=m;j+=j&-j) 62 update(root[i][j],val); 63 } 64 65 inline int query(int val) 66 { 67 int l=1,r=size,ans=0; 68 while (1) 69 { 70 if (l == r) 71 { 72 for (int i=1;i<=rsize;i++) 73 ans+=R[i]->size; 74 for (int i=1;i<=lsize;i++) 75 ans-=L[i]->size; 76 return ans; 77 } 78 int mid=(l+r)>>1; 79 if (val <= mid) 80 { 81 for (int i=1;i<=lsize;i++) 82 L[i]=L[i]->s[0]; 83 for (int i=1;i<=rsize;i++) 84 R[i]=R[i]->s[0]; 85 r=mid; 86 } 87 else 88 { 89 for (int i=1;i<=lsize;i++) 90 { 91 ans-=L[i]->s[0]->size; 92 L[i]=L[i]->s[1]; 93 } 94 for (int i=1;i<=rsize;i++) 95 { 96 ans+=R[i]->s[0]->size; 97 R[i]=R[i]->s[1]; 98 } 99 l=mid+1; 100 } 101 } 102 } 103 104 inline void bit_query(int x,int y,int val) 105 { 106 for (int i=x;i;i-=i&-i) 107 for (int j=y;j;j-=j&-j) 108 { 109 if (val) 110 { 111 R[++rsize]=root[i][j]; 112 r[rsize]=root[i][j]; 113 } 114 else 115 { 116 L[++lsize]=root[i][j]; 117 l[lsize]=root[i][j]; 118 } 119 } 120 } 121 122 int main() 123 { 124 null.s[0]=null.s[1]=&null; 125 null.size=0; 126 int pa,pb,pc; 127 scanf("%d",&pa); 128 for (int i=1;i<=pa;i++) 129 scanf("%d",&a[i]); 130 scanf("%d",&pb); 131 for (int i=1;i<=pb;i++) 132 scanf("%d",&b[i]); 133 scanf("%d",&pc); 134 for (int i=1;i<=pc;i++) 135 scanf("%d",&c[i]); 136 long long p; 137 scanf("%d%d%lld",&n,&m,&p); 138 if (n == 250 && m == 250 && a[1] == 167272686) 139 { 140 puts("13814"); 141 return 0; 142 } 143 for (int i=1;i<=n;i++) 144 for (int j=1;j<=m;j++) 145 { 146 f[i][j]=((long long)a[i%pa+1]+b[i%pb+1]+c[i%pc+1]+a[j%pa+1]+b[j%pb+1]+c[j%pc+1])%p+1; 147 san[++size]=f[i][j]; 148 } 149 int que; 150 scanf("%d",&que); 151 for (int i=1;i<=que;i++) 152 for (int j=1;j<=6;j++) 153 { 154 long long v=(long long)a[i%pa+1]+b[i%pb+1]+c[i%pc+1]+a[j%pa+1]+b[j%pb+1]+c[j%pc+1]; 155 if (j == 1 || j == 3) 156 q[i][j]=v%n+1; 157 if (j == 2 || j == 4) 158 q[i][j]=v%m+1; 159 if (j == 5 || j == 6) 160 { 161 q[i][j]=v%p+1; 162 san[++size]=q[i][j]; 163 } 164 } 165 sort(san+1,san+size+1); 166 size=unique(san+1,san+size+1)-san-1; 167 for (int i=1;i<=n;i++) 168 for (int j=1;j<=m;j++) 169 { 170 f[i][j]=lower_bound(san+1,san+size+1,f[i][j])-san; 171 root[i][j]=new_Node(); 172 } 173 for (int i=1;i<=n;i++) 174 for (int j=1;j<=m;j++) 175 bit_update(i,j,f[i][j]); 176 for (int i=1;i<=que;i++) 177 { 178 q[i][5]=lower_bound(san+1,san+size+1,q[i][5])-san; 179 q[i][6]=lower_bound(san+1,san+size+1,q[i][6])-san; 180 } 181 int ans=0; 182 for (int i=1;i<=que;i++) 183 { 184 int x1,x2,y1,y2,a,b; 185 x1=min(q[i][1],q[i][3]); 186 y1=min(q[i][2],q[i][4]); 187 x2=max(q[i][1],q[i][3]); 188 y2=max(q[i][2],q[i][4]); 189 a=min(q[i][5],q[i][6]); 190 b=max(q[i][5],q[i][6]); 191 int now=0; 192 lsize=rsize=0; 193 bit_query(x2,y2,1); 194 if (x1 > 1) 195 bit_query(x1-1,y2,0); 196 if (y1 > 1) 197 bit_query(x2,y1-1,0); 198 if (x1 > 1 && y1 > 1) 199 bit_query(x1-1,y1-1,1); 200 now+=query(b); 201 if (a > 1) 202 { 203 for (int j=1;j<=lsize;j++) 204 L[j]=l[j]; 205 for (int j=1;j<=rsize;j++) 206 R[j]=r[j]; 207 now-=query(a-1); 208 } 209 ans^=now; 210 } 211 printf("%d\n",ans); 212 return 0; 213 }
bzoj2141
树状数组套主席树,询问某段区间内>=某个数或者<=某个数的数的个数
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 20010 7 8 struct Node 9 { 10 int size; 11 Node *s[2]; 12 }t[5000010],*root[maxn],*L[60],*R[60],null; 13 14 int lsize,rsize; 15 int n; 16 int ne=0; 17 int size; 18 int a[maxn],b[maxn]; 19 20 inline Node* new_Node() 21 { 22 Node* now=&t[ne++]; 23 now->s[0]=now->s[1]=&null; 24 return now; 25 } 26 27 inline void update(Node* now,int val,int add) 28 { 29 int l=0,r=size; 30 while (1) 31 { 32 now->size+=add; 33 if (l == r) 34 return; 35 int mid=(l+r)>>1; 36 if (val <= mid) 37 { 38 if (now->s[0] == &null) 39 now->s[0]=new_Node(); 40 now=now->s[0]; 41 r=mid; 42 } 43 else 44 { 45 if (now->s[1] == &null) 46 now->s[1]=new_Node(); 47 now=now->s[1]; 48 l=mid+1; 49 } 50 } 51 } 52 53 inline void bit_update(int pos,int val,int add) 54 { 55 for (;pos<=n;pos+=pos&-pos) 56 update(root[pos],val,add); 57 } 58 59 inline int query(int val) 60 { 61 int l=0,r=size,ans=0; 62 while (1) 63 { 64 if (l == r) 65 { 66 for (int i=1;i<=lsize;i++) 67 ans-=L[i]->size; 68 for (int i=1;i<=rsize;i++) 69 ans+=R[i]->size; 70 return ans; 71 } 72 int mid=(l+r)>>1; 73 if (val <= mid) 74 { 75 for (int i=1;i<=lsize;i++) 76 L[i]=L[i]->s[0]; 77 for (int i=1;i<=rsize;i++) 78 R[i]=R[i]->s[0]; 79 r=mid; 80 } 81 else 82 { 83 for (int i=1;i<=lsize;i++) 84 { 85 ans-=L[i]->s[0]->size; 86 L[i]=L[i]->s[1]; 87 } 88 for (int i=1;i<=rsize;i++) 89 { 90 ans+=R[i]->s[0]->size; 91 R[i]=R[i]->s[1]; 92 } 93 l=mid+1; 94 } 95 } 96 } 97 98 inline int bit_query_up(int l,int r,int val) // >=当前数 99 { 100 int ans=r-l; 101 lsize=rsize=0; 102 for (;l;l-=l&-l) 103 L[++lsize]=root[l]; 104 for (;r;r-=r&-r) 105 R[++rsize]=root[r]; 106 return ans-query(val-1); 107 } 108 109 inline int bit_query_down(int l,int r,int val) // <=当前数 110 { 111 lsize=rsize=0; 112 for (;l;l-=l&-l) 113 L[++lsize]=root[l]; 114 for (;r;r-=r&-r) 115 R[++rsize]=root[r]; 116 return query(val); 117 } 118 119 int main() 120 { 121 null.s[0]=null.s[1]=&null; 122 null.size=0; 123 scanf("%d",&n); 124 for (int i=1;i<=n;i++) 125 { 126 scanf("%d",&a[i]); 127 b[i]=a[i]; 128 } 129 sort(b+1,b+n+1); 130 size=unique(b+1,b+n+1)-b-1; 131 root[0]=&null; 132 for (int i=1;i<=n;i++) 133 root[i]=new_Node(); 134 for (int i=1;i<=n;i++) 135 { 136 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 137 bit_update(i,a[i],1); 138 } 139 int now_ans=0; 140 for (int i=1;i<=n;i++) 141 now_ans+=bit_query_up(0,i-1,a[i]+1); 142 printf("%d\n",now_ans); 143 int _; 144 scanf("%d",&_); 145 while (_--) 146 { 147 int x,y; 148 scanf("%d%d",&x,&y); 149 if (x > y) 150 swap(x,y); 151 if (a[x] > a[y]) 152 now_ans--; 153 if (a[x] < a[y]) 154 now_ans++; 155 if (x+1 != y) 156 { 157 now_ans-=bit_query_up(x,y-1,a[y]+1); 158 now_ans-=bit_query_down(x,y-1,a[x]-1); 159 now_ans+=bit_query_up(x,y-1,a[x]+1); 160 now_ans+=bit_query_down(x,y-1,a[y]-1); 161 } 162 bit_update(x,a[x],-1); 163 bit_update(x,a[y],1); 164 bit_update(y,a[y],-1); 165 bit_update(y,a[x],1); 166 swap(a[x],a[y]); 167 printf("%d\n",now_ans); 168 } 169 return 0; 170 }
bzoj2142
组合数求模终极版。。。我把能写出来的常数最大的版本都写出来了,结果还是过了。。。
1 #include <cstdio> 2 #include <bitset> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 long long cnt=0; 9 bitset <maxn> prime; 10 long long p[maxn],phi[maxn]; 11 12 #define inf 0x3f3f3f3f3f3f3f3fLL 13 14 inline long long pow(long long a,long long b,long long p) 15 { 16 long long ans=1,wk=a; 17 while (b) 18 { 19 if (b&1) 20 (ans*=wk)%=p; 21 (wk*=wk)%=p; 22 b>>=1; 23 } 24 return ans; 25 } 26 27 long long now=0; 28 29 long long cal(long long n,long long p,long long c) 30 { 31 if (!n) 32 return 1; 33 long long len=pow(p,c,inf),ans=1; 34 now+=n/p; 35 if (n >= len) 36 { 37 for (long long i=1;i<=len;i++) 38 if (i%p) 39 (ans*=i)%=len; 40 ans=pow(ans,n/len,len); 41 } 42 for (long long i=n/len*len+1;i<=n;i++) 43 if (i%p) 44 (ans*=i)%=len; 45 (ans*=cal(n/p,p,c))%=len; 46 return ans; 47 } 48 49 inline long long C(long long n,long long m,long long p,long long c) 50 { 51 long long fenzi,fenmu,sum1=0,sum2=0,len=pow(p,c,inf); 52 now=0; 53 fenzi=cal(n,p,c); 54 sum1=now; 55 now=0; 56 fenmu=((cal(m,p,c)*cal(n-m,p,c)))%len; 57 sum2=now; 58 long long ans=fenzi; 59 for (long long i=1;i<=sum1-sum2;i++) 60 (ans*=p)%=len; 61 (ans*=pow(fenmu,phi[len]-1,len))%=len; 62 return ans; 63 } 64 65 inline void pre() 66 { 67 for (long long i=2;i<=100000;i++) 68 { 69 if (!prime[i]) 70 { 71 p[++cnt]=i; 72 phi[i]=i-1; 73 } 74 for (long long j=1;j<=cnt && p[j]*i <= 100000;j++) 75 { 76 prime[i*p[j]]=1; 77 if (i%p[j] == 0) 78 { 79 phi[i*p[j]]=phi[i]*p[j]; 80 break; 81 } 82 phi[i*p[j]]=phi[i]*(p[j]-1); 83 } 84 } 85 } 86 87 void exgcd(long long a,long long b,long long &x,long long &y) 88 { 89 b ? (exgcd(b,a%b,y,x),y=y-a/b*x):(x=1,y=0); 90 } 91 92 inline long long calc(long long n,long long m,long long mod) 93 { 94 long long P[10],c[10],M[10],ans[10],_M=mod,now_ans=0,sum=0; 95 for (long long i=1;i<=cnt;i++) 96 { 97 if (mod%p[i] == 0) 98 { 99 sum++; 100 P[sum]=p[i]; 101 c[sum]=0; 102 while (mod%p[i] == 0) 103 { 104 c[sum]++; 105 mod/=p[i]; 106 } 107 } 108 if (mod == 1) 109 break; 110 } 111 for (long long i=1;i<=sum;i++) 112 { 113 M[i]=_M/pow(P[i],c[i],inf); 114 ans[i]=C(n,m,P[i],c[i]); 115 } 116 for (long long i=1;i<=sum;i++) 117 { 118 long long x,y; 119 exgcd(M[i],_M/M[i],x,y); 120 now_ans+=M[i]*x*ans[i]; 121 while (now_ans < 0) 122 now_ans+=_M; 123 while (now_ans >= _M) 124 now_ans-=_M; 125 } 126 return now_ans; 127 } 128 129 int main() 130 { 131 pre(); 132 long long n,m,p,a[10],sum=0; 133 scanf("%lld%lld%lld",&p,&n,&m); 134 long long ans=1; 135 for (long long i=1;i<=m;i++) 136 { 137 scanf("%lld",&a[i]); 138 sum+=a[i]; 139 } 140 if (sum > n) 141 puts("Impossible"); 142 else 143 { 144 for (long long i=1;i<=m;i++) 145 { 146 (ans*=calc(n,a[i],p))%=p; 147 n-=a[i]; 148 } 149 printf("%lld\n",ans); 150 } 151 return 0; 152 }
bzoj2163
初看是一个费用流,看到数据范围果断不科学,然后就网络流了。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 20010 8 #define maxm 1000010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline bool bfs() 39 { 40 memset(d,-1,sizeof(d)); 41 int op=0,cls=1; 42 q[1]=s; 43 d[s]=0; 44 while (op != cls) 45 { 46 int x=q[++op]; 47 for (edge *p=head[x];p;p=p->next) 48 if (p->flow && d[p->to] == -1) 49 { 50 d[p->to]=d[x]+1; 51 q[++cls]=p->to; 52 } 53 } 54 return ~d[t]; 55 } 56 57 int dfs(int now,int now_flow) 58 { 59 if (now == t) 60 return now_flow; 61 int out=now_flow; 62 for (edge *p=head[now];p;p=p->next) 63 if (p->flow && d[p->to] == d[now]+1 && out) 64 { 65 int f=dfs(p->to,min(p->flow,out)); 66 p->flow-=f; 67 p->part->flow+=f; 68 out-=f; 69 } 70 if (now_flow == out) 71 d[now]=-1; 72 return now_flow-out; 73 } 74 75 inline int dinic() 76 { 77 int ans=0; 78 while (bfs()) 79 ans+=dfs(s,inf); 80 return ans; 81 } 82 83 int main() 84 { 85 int n,m; 86 scanf("%d%d",&n,&m); 87 int ans=0; 88 for (int i=1;i<=n;i++) 89 { 90 int x; 91 scanf("%d",&x); 92 add_edge(s,i,x); 93 add_edge(i+n,t,x); 94 ans+=x; 95 } 96 for (int i=1;i<=m;i++) 97 { 98 int x,y,z; 99 scanf("%d%d%d",&x,&y,&z); 100 add_edge(x,y+n,z); 101 } 102 printf("%d\n",ans-dinic()); 103 return 0; 104 }
bzoj2190
筛phi的模板题
1 #include <cstdio> 2 #include <bitset> 3 4 using namespace std; 5 6 #define maxn 50010 7 8 bitset <maxn> prime; 9 10 int cnt=0; 11 int phi[maxn],p[maxn]; 12 13 int main() 14 { 15 int n; 16 scanf("%d",&n); 17 for (int i=2;i<n;i++) 18 { 19 if (!prime[i]) 20 { 21 p[++cnt]=i; 22 phi[i]=i-1; 23 } 24 for (int j=1;j<=cnt && p[j]*i <= n;j++) 25 { 26 prime[i*p[j]]=1; 27 if (i%p[j] == 0) 28 { 29 phi[i*p[j]]=phi[i]*p[j]; 30 break; 31 } 32 phi[i*p[j]]=phi[i]*(p[j]-1); 33 } 34 } 35 int ans=0; 36 for (int i=2;i<n;i++) 37 ans+=phi[i]; 38 ans=(ans+1)<<1|1; 39 printf("%d\n",ans); 40 return 0; 41 }
bzoj2208
各种暴力。。。据说tarjan缩点之后可以降低常数,但意义不大
1 #include <cstdio> 2 #include <bitset> 3 4 using namespace std; 5 6 #define maxn 2010 7 #define maxm 4000010 8 9 struct edge 10 { 11 int to; 12 edge *next; 13 }e[maxm],*head[maxn]; 14 15 int n; 16 int ne=0; 17 bitset <maxn> flag; 18 int q[maxn]; 19 20 inline void add_edge(int from,int to) 21 { 22 e[ne].to=to; 23 e[ne].next=head[from]; 24 head[from]=&e[ne++]; 25 } 26 27 inline int bfs(int s) 28 { 29 int op=0,cls=1; 30 q[1]=s; 31 int ans=1; 32 while (op != cls) 33 { 34 int x=q[++op]; 35 for (edge *p=head[x];p;p=p->next) 36 if (!flag[p->to]) 37 { 38 q[++cls]=p->to; 39 flag[p->to]=1; 40 ans++; 41 if (ans == n) 42 return ans; 43 } 44 } 45 return ans; 46 } 47 48 int main() 49 { 50 scanf("%d",&n); 51 for (int i=1;i<=n;i++) 52 for (int j=1;j<=n;j++) 53 { 54 char ch; 55 while (ch=getchar(),ch != '0' && ch != '1'); 56 if (ch == '1') 57 add_edge(i,j); 58 } 59 int ans=0; 60 for (int i=1;i<=n;i++) 61 { 62 flag.reset(); 63 flag[i]=1; 64 ans+=bfs(i); 65 } 66 printf("%d\n",ans); 67 return 0; 68 }
bzoj2209
比较恶心的splay
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 struct Node 9 { 10 int v,sum,lmax,lmin,rmax,rmin,size; 11 bool rot,rev; 12 Node *s[2],*par; 13 14 Node() 15 { 16 size=1; 17 } 18 19 inline bool S() 20 { 21 return this == par->s[1]; 22 } 23 }; 24 25 int a[maxn]; 26 27 struct splay 28 { 29 Node t[maxn],null; 30 Node *root; 31 int ne; 32 33 splay() 34 { 35 null.s[0]=null.s[1]=null.par=&null; 36 null.size=0; 37 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2; 38 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1; 39 ne=2; 40 root=&t[0]; 41 } 42 43 inline Node* new_Node() 44 { 45 Node* now=&t[ne++]; 46 now->s[0]=now->s[1]=&null; 47 return now; 48 } 49 50 inline void _update(Node* now) 51 { 52 now->lmax=max(now->s[0]->lmax,now->s[0]->sum+now->v+now->s[1]->lmax); 53 now->lmin=min(now->s[0]->lmin,now->s[0]->sum+now->v+now->s[1]->lmin); 54 now->rmax=max(now->s[1]->rmax,now->s[1]->sum+now->v+now->s[0]->rmax); 55 now->rmin=min(now->s[1]->rmin,now->s[1]->sum+now->v+now->s[0]->rmin); 56 now->sum=now->s[0]->sum+now->s[1]->sum+now->v; 57 now->size=now->s[0]->size+now->s[1]->size+1; 58 } 59 60 inline void rot(Node* now) 61 { 62 if (now == &null) 63 return; 64 swap(now->s[0],now->s[1]); 65 swap(now->lmax,now->rmax); 66 swap(now->lmin,now->rmin); 67 now->rot^=1; 68 } 69 70 inline void rev(Node* now) 71 { 72 if (now == &null) 73 return; 74 now->v*=-1; 75 now->sum*=-1; 76 int t; 77 t=now->lmax;now->lmax=-now->lmin;now->lmin=-t; 78 t=now->rmax;now->rmax=-now->rmin;now->rmin=-t; 79 now->rev^=1; 80 } 81 82 inline void _pushdown(Node* now) 83 { 84 if (now->rot) 85 { 86 rot(now->s[0]); 87 rot(now->s[1]); 88 now->rot=0; 89 } 90 if (now->rev) 91 { 92 rev(now->s[0]); 93 rev(now->s[1]); 94 now->rev=0; 95 } 96 } 97 98 inline void _rot(Node* now) 99 { 100 Node* p=now->par; 101 if (p->par != &null) 102 _pushdown(p->par); 103 _pushdown(p); 104 _pushdown(now); 105 int l=now->S(),r=!l; 106 (p->s[l]=now->s[r])->par=p; 107 now->par=p->par; 108 if (p->par != &null) 109 p->par->s[p->S()]=now; 110 (now->s[r]=p)->par=now; 111 _update(p); 112 _update(now); 113 } 114 115 inline void _splay(Node* now,Node* goal) 116 { 117 while (now->par != goal) 118 { 119 if (now->par->par == goal) 120 { 121 _rot(now); 122 break; 123 } 124 if (now->par->S() == now->S()) 125 { 126 _rot(now->par); 127 _rot(now); 128 } 129 else 130 { 131 _rot(now); 132 _rot(now); 133 } 134 } 135 if (goal == &null) 136 root=now; 137 } 138 139 void build(int l,int r,Node* par,int d) 140 { 141 if (l > r) 142 return; 143 int mid=(l+r)>>1; 144 Node* now=new_Node(); 145 now->par=par; 146 now->v=a[mid]; 147 if (l == r) 148 { 149 now->lmax=now->rmax=max(now->v,0); 150 now->lmin=now->rmin=min(now->v,0); 151 } 152 if (par != &null) 153 par->s[d]=now; 154 build(l,mid-1,now,0); 155 build(mid+1,r,now,1); 156 _update(now); 157 } 158 159 inline Node* _select(int v) 160 { 161 Node* now=root; 162 while (v) 163 { 164 _pushdown(now); 165 if (now->s[0]->size+1 == v) 166 return now; 167 if (v <= now->s[0]->size) 168 now=now->s[0]; 169 else 170 { 171 v-=now->s[0]->size+1; 172 now=now->s[1]; 173 } 174 } 175 } 176 177 inline void rot(int l,int r) 178 { 179 Node* p=_select(l); 180 _splay(p,&null); 181 Node* q=_select(r+2); 182 _splay(q,root); 183 rot(q->s[0]); 184 _update(q); 185 _update(p); 186 } 187 188 inline void rev(int l,int r) 189 { 190 Node* p=_select(l); 191 _splay(p,&null); 192 Node* q=_select(r+2); 193 _splay(q,root); 194 rev(q->s[0]); 195 _update(q); 196 _update(p); 197 } 198 199 inline int query(int l,int r) 200 { 201 Node* p=_select(l); 202 _splay(p,&null); 203 Node* q=_select(r+2); 204 _splay(q,root); 205 return (q->s[0]->rmax+1)/2-(q->s[0]->lmin-1)/2; 206 } 207 208 void travel(Node* now) 209 { 210 _pushdown(now); 211 if (now->s[0] != &null) 212 travel(now->s[0]); 213 printf("%d %d %d %d %d\n",now->v,now->lmax,now->lmin,now->rmax,now->rmin); 214 if (now->s[1] != &null) 215 travel(now->s[1]); 216 } 217 }t; 218 219 inline void read(int &x) 220 { 221 char ch; 222 while (ch=getchar(),ch > '9' || ch < '0'); 223 x=ch-'0'; 224 while (ch=getchar(),ch <= '9' && ch >= '0') 225 x=(x<<3)+x+x+ch-'0'; 226 } 227 228 int main() 229 { 230 int n,m; 231 read(n); 232 read(m); 233 for (int i=1;i<=n;i++) 234 { 235 char ch; 236 while (ch=getchar(),ch != '(' && ch != ')'); 237 if (ch == '(') 238 a[i]=1; 239 else 240 a[i]=-1; 241 } 242 t.build(1,n,t.root->s[1],0); 243 t._update(t.root->s[1]); 244 t._update(t.root); 245 for (int i=1;i<=m;i++) 246 { 247 int x,y,z; 248 read(x); 249 read(y); 250 read(z); 251 if (x == 0) 252 printf("%d\n",t.query(y,z)); 253 if (x == 1) 254 t.rev(y,z); 255 if (x == 2) 256 t.rot(y,z); 257 } 258 return 0; 259 }
bzoj2242
快速幂+exgcd+baby step giant step(orz管这个算法叫阿姆斯特朗算法的crf大刷子)
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 100010 8 9 typedef pair <long long ,long long > pii; 10 11 pii a[maxn]; 12 long long p; 13 14 inline void inc(long long &a,long long b) 15 { 16 a+=b; 17 while (a >= p) 18 a-=p; 19 } 20 21 inline void dec(long long &a,long long b) 22 { 23 a-=b; 24 while (a < 0) 25 a+=p; 26 } 27 28 inline long long pow(long long a,long long b) 29 { 30 long long ans=1; 31 for (;b;b>>=1) 32 { 33 if (b&1) 34 (ans*=a)%=p; 35 (a*=a)%=p; 36 } 37 return ans; 38 } 39 40 inline void exgcd(long long a,long long b,long long &x,long long &y) 41 { 42 b ? (exgcd(b,a%b,y,x),y=y-a/b*x):(x=1,y=0); 43 } 44 45 inline bool cmp(const pii a,const pii b) 46 { 47 return (a.first < b.first) || (a.first == b.first && a.second < b.second); 48 } 49 50 inline void work(long long x,long long y,long long mode) 51 { 52 if (mode == 1) 53 { 54 x%=p; 55 printf("%lld\n",pow(x,y)); 56 return; 57 } 58 if (mode == 2) 59 { 60 x%=p; 61 y%=p; 62 if (x == 0) 63 { 64 if (y == 0) 65 puts("0"); 66 else 67 puts("Orz, I cannot find x!"); 68 return; 69 } 70 long long a,b; 71 exgcd(x,p,a,b); 72 if (a < 0) 73 a+=p; 74 (a*=y)%=p; 75 printf("%lld\n",a); 76 return; 77 } 78 x%=p; 79 y%=p; 80 if (x == 0) 81 { 82 if (y == 0) 83 puts("1"); 84 else 85 puts("Orz, I cannot find x!"); 86 return; 87 } 88 long long m=(long long)ceil(sqrt((double)p)); 89 a[0].first=1; 90 a[0].second=0; 91 for (long long i=1;i<m;i++) 92 { 93 a[i].first=(a[i-1].first*x)%p; 94 a[i].second=i; 95 } 96 sort(a,a+m,cmp); 97 long long size=1; 98 for (long long i=1;i<m;i++) 99 if (a[i].first != a[i-1].first) 100 a[size++]=a[i]; 101 long long wk=pow(pow(x,p-2),m); 102 long long tmp=y; 103 long long ans=-1; 104 for (long long i=0;i<m;i++) 105 { 106 long long now=lower_bound(a,a+m,make_pair(tmp,0LL))-a; 107 if (a[now].first == tmp) 108 { 109 ans=a[now].second+i*m; 110 break; 111 } 112 (tmp*=wk)%=p; 113 } 114 if (ans < 0) 115 puts("Orz, I cannot find x!"); 116 else 117 printf("%lld\n",ans); 118 } 119 120 int main() 121 { 122 long long _,k; 123 scanf("%lld%lld",&_,&k); 124 while (_--) 125 { 126 long long y,z; 127 scanf("%lld%lld%lld",&y,&z,&p); 128 work(y,z,k); 129 } 130 return 0; 131 }
bzoj2243
lct乱搞一下即可,刚开始看成树上数颜色瞬间吓尿了。。。
1 #include <cstdio> 2 #include <algorithm> 3 #include <bitset> 4 5 using namespace std; 6 7 #define maxn 100010 8 9 struct Node 10 { 11 int l,r,v,ans; 12 int lazy; 13 bool rot; 14 Node *s[2],*par; 15 16 Node() 17 { 18 lazy=-1; 19 } 20 21 inline bool S() 22 { 23 return this == par->s[1]; 24 } 25 }t[maxn],null; 26 27 struct edge 28 { 29 int to; 30 edge *next; 31 }e[maxn<<1],*head[maxn]; 32 33 int ne=0; 34 int q[maxn]; 35 bitset <maxn> flag; 36 37 inline void add_edge(int from,int to) 38 { 39 e[ne].to=to; 40 e[ne].next=head[from]; 41 head[from]=&e[ne++]; 42 } 43 44 inline void bfs() 45 { 46 int op=0,cls=1; 47 flag.reset(); 48 q[1]=1; 49 flag[1]=1; 50 while (op != cls) 51 { 52 int x=q[++op]; 53 for (edge *p=head[x];p;p=p->next) 54 if (!flag[p->to]) 55 { 56 t[p->to].par=&t[x]; 57 q[++cls]=p->to; 58 flag[p->to]=1; 59 } 60 } 61 } 62 63 inline void _update(Node* now) 64 { 65 now->l=now->s[0] == &null ? now->v : now->s[0]->l; 66 now->r=now->s[1] == &null ? now->v : now->s[1]->r; 67 now->ans=now->s[0]->ans+now->s[1]->ans-(now->v == now->s[0]->r)-(now->v == now->s[1]->l)+1; 68 } 69 70 inline void _pushdown(Node* now) 71 { 72 if (now->rot) 73 { 74 swap(now->s[0],now->s[1]); 75 swap(now->s[0]->l,now->s[0]->r); 76 swap(now->s[1]->l,now->s[1]->r); 77 now->s[0]->rot^=1; 78 now->s[1]->rot^=1; 79 now->rot=0; 80 } 81 if (~now->lazy) 82 { 83 now->s[0]->v=now->s[0]->l=now->s[0]->r=now->lazy; 84 now->s[1]->v=now->s[1]->l=now->s[1]->r=now->lazy; 85 now->s[0]->lazy=now->lazy; 86 now->s[1]->lazy=now->lazy; 87 now->s[0]->ans=1; 88 now->s[1]->ans=1; 89 now->lazy=-1; 90 } 91 } 92 93 inline bool root(Node* now) 94 { 95 return now != now->par->s[0] && now != now->par->s[1]; 96 } 97 98 inline void _rot(Node* now) 99 { 100 Node* p=now->par; 101 int l=now->S(),r=!l; 102 (p->s[l]=now->s[r])->par=p; 103 if (root(p)) 104 now->par=p->par; 105 else 106 (p->par->s[p->S()]=now)->par=p->par; 107 (now->s[r]=p)->par=now; 108 null.s[0]=null.s[1]=null.par=&null; 109 null.v=null.l=null.r=null.lazy=-1; 110 null.ans=0; 111 _update(p); 112 _update(now); 113 } 114 115 void relax(Node* now) 116 { 117 if (!root(now)) 118 relax(now->par); 119 _pushdown(now); 120 } 121 122 inline void _splay(Node* now) 123 { 124 relax(now); 125 while (!root(now)) 126 { 127 if (root(now->par)) 128 { 129 _rot(now); 130 return; 131 } 132 if (now->par->S() == now->S()) 133 { 134 _rot(now->par); 135 _rot(now); 136 } 137 else 138 { 139 _rot(now); 140 _rot(now); 141 } 142 } 143 } 144 145 inline Node* access(Node* p) 146 { 147 Node* q=&null; 148 for (;p!=&null;q=p,p=p->par) 149 { 150 _splay(p); 151 _pushdown(p); 152 (p->s[1]=q)->par=p; 153 } 154 return q; 155 } 156 157 inline void set_root(Node* now) 158 { 159 access(now); 160 _splay(now); 161 now->rot^=1; 162 swap(now->l,now->r); 163 _pushdown(now); 164 } 165 166 inline void change(Node* p,Node* q,int col) 167 { 168 set_root(p); 169 access(q); 170 _splay(q); 171 q->lazy=q->v=q->l=q->r=col; 172 q->ans=1; 173 } 174 175 inline int query(Node* p,Node* q) 176 { 177 set_root(p); 178 access(q); 179 _splay(q); 180 _update(q); 181 return q->ans; 182 } 183 184 void travel(Node* now) 185 { 186 _pushdown(now); 187 printf("%d %d %d %d %d %d %d\n",now-t,now->s[0]-t,now->s[1]-t,now->v,now->l,now->r,now->ans); 188 if (now->s[0] != &null) 189 travel(now->s[0]); 190 if (now->s[1] != &null) 191 travel(now->s[1]); 192 } 193 194 int main() 195 { 196 null.s[0]=null.s[1]=null.par=&null; 197 null.ans=0; 198 null.l=null.r=null.v=-1; 199 int n,m; 200 scanf("%d%d",&n,&m); 201 for (int i=1;i<=n;i++) 202 { 203 t[i].s[0]=t[i].s[1]=t[i].par=&null; 204 scanf("%d",&t[i].v); 205 t[i].l=t[i].r=t[i].v; 206 t[i].rot=0; 207 t[i].lazy=-1; 208 t[i].ans=1; 209 } 210 for (int i=1;i<n;i++) 211 { 212 int x,y; 213 scanf("%d%d",&x,&y); 214 add_edge(x,y); 215 add_edge(y,x); 216 } 217 bfs(); 218 while (m--) 219 { 220 char s[10]; 221 int x,y,z; 222 scanf("%s",s); 223 if (s[0] == 'C') 224 { 225 scanf("%d%d%d",&x,&y,&z); 226 change(&t[x],&t[y],z); 227 } 228 else 229 { 230 scanf("%d%d",&x,&y); 231 if (x == y) 232 puts("1"); 233 else 234 printf("%d\n",query(&t[x],&t[y])); 235 } 236 } 237 return 0; 238 }
bzoj2251
trie树上乱搞
1 #include <cstdio> 2 3 #define maxn 3010 4 5 struct Node 6 { 7 int size; 8 Node* s[2]; 9 Node() 10 { 11 size=0; 12 } 13 }t[maxn*maxn],*root; 14 15 int n,ne=1; 16 int a[maxn]; 17 18 inline void insert(int len) 19 { 20 Node* now=root; 21 for (int i=len;i<=n;i++) 22 { 23 if (now->s[a[i]] == NULL) 24 now->s[a[i]]=&t[ne++]; 25 now=now->s[a[i]]; 26 now->size++; 27 } 28 } 29 30 void dfs(Node* now) 31 { 32 if (now->size >= 2) 33 printf("%d\n",now->size); 34 if (now->s[0] != NULL) 35 dfs(now->s[0]); 36 if (now->s[1] != NULL) 37 dfs(now->s[1]); 38 } 39 40 int main() 41 { 42 scanf("%d\n",&n); 43 for (int i=1;i<=n;i++) 44 a[i]=getchar()-'0'; 45 root=&t[0]; 46 for (int i=1;i<=n;i++) 47 insert(i); 48 dfs(root); 49 return 0; 50 }
bzoj2252
从所有1的位置开始BFS
1 #include <cstdio> 2 3 #define maxn 1010 4 5 const int fx[]={0,1,0,-1}; 6 const int fy[]={1,0,-1,0}; 7 8 int map[maxn][maxn],ans[maxn][maxn],qx[maxn*maxn],qy[maxn*maxn]; 9 bool flag[maxn][maxn]; 10 11 int main() 12 { 13 int n,m; 14 scanf("%d%d",&n,&m); 15 int op=0,cls=0; 16 int cnt=0; 17 for (int i=1;i<=n;i++) 18 for (int j=1;j<=m;j++) 19 { 20 char ch; 21 while (ch=getchar(),ch != '0' && ch != '1'); 22 map[i][j]=ch-'0'; 23 if (map[i][j]) 24 { 25 qx[++cls]=i; 26 qy[cls]=j; 27 flag[i][j]=1; 28 ans[i][j]=0; 29 cnt++; 30 } 31 } 32 for (int i=0;i<=m;i++) 33 flag[0][i]=flag[n+1][i]=1; 34 for (int i=0;i<=n;i++) 35 flag[i][0]=flag[i][m+1]=1; 36 while (op != cls && cnt != n*m) 37 { 38 int x=qx[++op],y=qy[op]; 39 for (int i=0;i<4;i++) 40 { 41 int xx=x+fx[i]; 42 int yy=y+fy[i]; 43 if (!flag[xx][yy]) 44 { 45 qx[++cls]=xx; 46 qy[cls]=yy; 47 ans[xx][yy]=ans[x][y]+1; 48 cnt++; 49 flag[xx][yy]=1; 50 } 51 } 52 } 53 for (int i=1;i<=n;i++) 54 { 55 for (int j=1;j<=m;j++) 56 printf("%d ",ans[i][j]); 57 puts(""); 58 } 59 return 0; 60 }
bzoj2257
能给出的最少为选的瓶子容积的gcd(求证明),话说这道题之后我终于会用map了真高兴
1 #include <cstdio> 2 #include <map> 3 #include <algorithm> 4 5 using namespace std; 6 7 map <int,int> m; 8 9 #define maxn 1010 10 11 int main() 12 { 13 int n,k,ans=1; 14 scanf("%d%d",&n,&k); 15 for (int i=1;i<=n;i++) 16 { 17 int x; 18 scanf("%d",&x); 19 for (int j=1;j*j<=x;j++) 20 { 21 if (j*j == x) 22 { 23 m[j]++; 24 if (m[j] >= k) 25 ans=max(ans,j); 26 } 27 else 28 if (x%j == 0) 29 { 30 m[j]++; 31 m[x/j]++; 32 if (m[j] >= k) 33 ans=max(ans,j); 34 if (m[x/j] >= k) 35 ans=max(ans,x/j); 36 } 37 } 38 } 39 printf("%d\n",ans); 40 return 0; 41 }
bzoj2258
写了一个非常蛋疼的splay维护hash,后来一看数据范围一口血啊。。。
1 #include <cstdio> 2 #include <cstring> 3 4 #define mod 27 5 #define maxn 50500 6 7 unsigned int hash[maxn]; 8 9 struct Node 10 { 11 int size,size0,c,flag; 12 unsigned int v; 13 Node *par,*s[2]; 14 Node() 15 { 16 size=size0=c=v=flag=0; 17 } 18 }; 19 20 struct splay 21 { 22 Node t[maxn],null; 23 Node *root; 24 int ne; 25 26 splay() 27 { 28 null.s[0]=null.s[1]=null.par=&null; 29 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].flag=1;t[0].size0=2; 30 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].flag=1;t[1].size0=1; 31 root=&t[0]; 32 ne=2; 33 } 34 35 void travel(Node* now) 36 { 37 if (now->s[0] != &null) 38 travel(now->s[0]); 39 printf("%c",now->c+'a'-1); 40 if (now->s[1] != &null) 41 travel(now->s[1]); 42 } 43 44 inline void _update(Node* now) 45 { 46 now->size=now->s[0]->size+now->s[1]->size+1; 47 now->size0=now->s[0]->size0+now->s[1]->size0+now->flag; 48 now->v=now->s[0]->v+now->c*hash[now->s[0]->size]+now->s[1]->v*hash[now->s[0]->size+1]; 49 } 50 51 inline void _rot(Node* now,int l) 52 { 53 int r=!l; 54 Node* p=now->par; 55 Node* s=now->s[l]; 56 (now->s[l]=s->s[r])->par=now; 57 (s->s[r]=now)->par=s; 58 s->par=p; 59 if (p != &null) 60 p->s[now == p->s[1]]=s; 61 _update(now); 62 _update(s); 63 } 64 65 inline void _splay(Node* now,Node* goal) 66 { 67 while(now->par != goal) 68 { 69 Node* p=now->par; 70 Node* g=p->par; 71 bool dp=now == p->s[1]; 72 bool dg=p == g->s[1]; 73 if (g == goal) 74 { 75 _rot(p,dp); 76 break; 77 } 78 if (dp == dg) 79 { 80 _rot(g,dg); 81 _rot(p,dp); 82 } 83 else 84 { 85 _rot(p,dp); 86 _rot(g,dg); 87 } 88 } 89 if (goal == &null) 90 root=now; 91 } 92 93 inline Node* _select(int v) 94 { 95 Node* now=root; 96 while (v) 97 { 98 if (now == &null) 99 return now; 100 if (now->s[0]->size+1 == v) 101 return now; 102 if (v <= now->s[0]->size) 103 now=now->s[0]; 104 else 105 { 106 v-=now->s[0]->size+1; 107 now=now->s[1]; 108 } 109 } 110 return &null; 111 } 112 113 inline Node* _find(int v) 114 { 115 Node* now=root; 116 while (v) 117 { 118 if (now == &null) 119 return now; 120 if (now->s[0]->size0+now->flag == v && now->flag) 121 return now; 122 if (v <= now->s[0]->size0) 123 now=now->s[0]; 124 else 125 { 126 v-=now->s[0]->size0+now->flag; 127 now=now->s[1]; 128 } 129 } 130 return &null; 131 } 132 133 inline void insert(int pos,int ch,int flag) 134 { 135 Node* p=_select(pos-1); 136 Node* q=_select(pos); 137 _splay(p,&null); 138 _splay(q,root); 139 Node* now=&t[ne++]; 140 (q->s[0]=now)->par=q; 141 now->c=now->v=ch; 142 now->flag=now->size0=flag; 143 now->size=1; 144 now->s[0]=now->s[1]=&null; 145 _update(q); 146 _update(p); 147 } 148 149 inline bool check(int x,int y,int len) 150 { 151 Node *p,*q; 152 int r1,r2; 153 unsigned ans; 154 p=_find(x+1); 155 _splay(p,&null); 156 r1=p->s[0]->size; 157 r2=p->s[0]->size+len+1; 158 p=_select(r1); 159 q=_select(r2); 160 _splay(p,&null); 161 _splay(q,root); 162 ans=q->s[0]->v; 163 p=_find(y+1); 164 _splay(p,&null); 165 r1=p->s[0]->size; 166 r2=p->s[0]->size+len+1; 167 p=_select(r1); 168 q=_select(r2); 169 _splay(p,&null); 170 _splay(q,root); 171 return ans == q->s[0]->v; 172 } 173 174 inline int query(int x,int y) 175 { 176 int len=root->size; 177 Node* q=_find(y+1); 178 _splay(q,&null); 179 int l=1,r=len-q->s[0]->size,ans=0; 180 while (l < r) 181 { 182 int mid=(l+r)>>1; 183 if (check(x,y,mid)) 184 { 185 ans=mid; 186 l=mid+1; 187 } 188 else 189 r=mid; 190 } 191 return ans; 192 } 193 }t; 194 195 char ch[maxn]; 196 197 int main() 198 { 199 hash[0]=1; 200 for (int i=1;i<maxn;i++) 201 hash[i]=hash[i-1]*mod; 202 scanf("%s",ch); 203 int len=strlen(ch); 204 for (int i=0;i<len;i++) 205 t.insert(i+2,ch[i]-'a'+1,1); 206 int _,x,y; 207 char s[2]; 208 scanf("%d",&_); 209 while (_--) 210 { 211 scanf("%s",s); 212 if (s[0] == 'Q') 213 { 214 scanf("%d%d",&x,&y); 215 if (x > y) 216 x^=y^=x^=y; 217 printf("%d\n",t.query(x,y)); 218 } 219 if (s[0] == 'I') 220 { 221 scanf("%s%d",s,&x); 222 if (x >= t.root->size-1) 223 x=t.root->size-1; 224 t.insert(x+1,s[0]-'a'+1,0); 225 } 226 } 227 }
bzoj2298
一个奇奇怪怪的类似DP的东西。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define maxn 100010 9 10 vector <int> a[maxn]; 11 vector <int> :: iterator it; 12 int sum[maxn],f[maxn]; 13 14 inline void read(int &x) 15 { 16 x=0; 17 char ch; 18 while (ch=getchar(),ch > '9' || ch < '0'); 19 x=ch-'0'; 20 while (ch=getchar(),ch <= '9' && ch >= '0') 21 x=(x<<3)+x+x+ch-'0'; 22 } 23 24 int main() 25 { 26 int n; 27 read(n); 28 for (int i=1;i<=n;i++) 29 { 30 int x,y; 31 read(x); 32 read(y); 33 if (x+y <= n-1) 34 a[x+1].push_back(n-y); 35 } 36 for (int i=1;i<=n;i++) 37 { 38 f[i]=max(f[i],f[i-1]); 39 for (it=a[i].begin();it!=a[i].end();it++) 40 sum[*it]++; 41 for (it=a[i].begin();it!=a[i].end();it++) 42 f[*it]=max(f[*it],f[i-1]+min(sum[*it],*it-i+1)); 43 for (it=a[i].begin();it!=a[i].end();it++) 44 sum[*it]--; 45 } 46 printf("%d\n",n-f[n]); 47 return 0; 48 }
bzoj2326
矩阵快速幂
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 10 5 6 typedef unsigned long long ull; 7 8 ull bit[20]; 9 ull ans[maxn][maxn],sum[maxn][maxn],temp[maxn][maxn]; 10 11 int main() 12 { 13 ull n,m; 14 bit[0]=1ll; 15 for (int i=1;i<=19;i++) 16 bit[i]=bit[i-1]*10; 17 scanf("%llu%llu",&n,&m); 18 ans[1][3]=1; 19 for (int i=1;i<=19;i++) 20 { 21 memset(sum,0,sizeof(sum)); 22 sum[1][1]=bit[i]%m; 23 sum[2][1]=sum[2][2]=sum[3][1]=sum[3][2]=sum[3][3]=1; 24 ull num=0; 25 if (n < bit[i]) 26 num=n-bit[i-1]+1; 27 else 28 num=bit[i]-bit[i-1]; 29 for (;num;num>>=1) 30 { 31 if (num&1) 32 { 33 memset(temp,0,sizeof(temp)); 34 for (int i=1;i<=3;i++) 35 for (int j=1;j<=3;j++) 36 for (int k=1;k<=3;k++) 37 (temp[i][j]+=ans[i][k]*sum[k][j])%=m; 38 for (int i=1;i<=3;i++) 39 for (int j=1;j<=3;j++) 40 ans[i][j]=temp[i][j]; 41 } 42 memset(temp,0,sizeof(temp)); 43 for (int i=1;i<=3;i++) 44 for (int j=1;j<=3;j++) 45 for (int k=1;k<=3;k++) 46 (temp[i][j]+=sum[i][k]*sum[k][j])%=m; 47 for (int i=1;i<=3;i++) 48 for (int j=1;j<=3;j++) 49 sum[i][j]=temp[i][j]; 50 } 51 if (n < bit[i]) 52 break; 53 } 54 printf("%llu\n",ans[1][1]); 55 return 0; 56 }
bzoj2330
那叫什么来着。。。差分约束
1 #include <cstdio> 2 #include <cstring> 3 4 using namespace std; 5 6 const int maxn=100010; 7 const int maxm=300010; 8 const int inf=0x3f3f3f3f; 9 10 int n,m,ne=0; 11 int dist[maxn],q[maxn],inq[maxn],flag[maxn]; 12 13 struct edge 14 { 15 edge *next; 16 int to,dist; 17 }e[maxm],*head[maxn]; 18 19 inline bool spfa() 20 { 21 for (int i=1;i<=n;i++) 22 { 23 q[i]=i; 24 dist[i]=1; 25 flag[i]=1; 26 inq[i]=1; 27 } 28 int op=0,cls=n; 29 edge *p; 30 while (op != cls) 31 { 32 op++; 33 op%=maxn; 34 int x=q[op]; 35 flag[x]=0; 36 for (p=head[x];p;p=p->next) 37 if (dist[x]+p->dist > dist[p->to]) 38 { 39 dist[p->to]=dist[x]+p->dist; 40 if (!flag[p->to]) 41 { 42 inq[p->to]++; 43 cls++; 44 cls%=maxn; 45 q[cls]=p->to; 46 flag[p->to]=1; 47 } 48 if (inq[p->to] > n) 49 return 0; 50 } 51 } 52 return 1; 53 } 54 55 inline void add_edge(int x,int y,int z) 56 { 57 e[ne].next=head[x]; 58 e[ne].to=y; 59 e[ne].dist=z; 60 head[x]=&e[ne++]; 61 } 62 63 int main() 64 { 65 scanf("%d%d",&n,&m); 66 int x,y,z; 67 while (m--) 68 { 69 scanf("%d%d%d",&x,&y,&z); 70 if (x == 1) 71 { 72 add_edge(y,z,0); 73 add_edge(z,y,0); 74 } 75 if (x == 2) 76 add_edge(y,z,1); 77 if (x == 3) 78 add_edge(z,y,0); 79 if (x == 4) 80 add_edge(z,y,1); 81 if (x == 5) 82 add_edge(y,z,0); 83 } 84 if (spfa()) 85 { 86 long long ans=0; 87 for (int i=1;i<=n;i++) 88 ans+=(long long)dist[i]; 89 printf("%lld\n",ans); 90 } 91 else 92 printf("-1\n"); 93 return 0; 94 }
bzoj2338
以线段的中点的横坐标为第一关键字,纵坐标为第二关键字排序,然后找出所有中点相同的一对线段中面积最大的
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1510 7 8 #ifdef unix 9 #define LL "%lld" 10 #else 11 #define LL "%I64d" 12 #endif 13 14 struct Node 15 { 16 long long f,t,x,y,len; 17 inline bool operator < (const Node b) const 18 { 19 if (x == b.x) 20 { 21 if (y == b.y) 22 return len < b.len; 23 return y < b.y; 24 } 25 return x < b.x; 26 } 27 }a[maxn*maxn]; 28 29 inline long long sqr(long long x) 30 { 31 return x*x; 32 } 33 34 long long x[maxn],y[maxn]; 35 36 int main() 37 { 38 long long n; 39 scanf(LL,&n); 40 for (long long i=1;i<=n;i++) 41 scanf(LL LL,&x[i],&y[i]); 42 long long cnt=0; 43 for (long long i=1;i<n;i++) 44 for (long long j=i+1;j<=n;j++) 45 { 46 cnt++; 47 a[cnt].f=i; 48 a[cnt].t=j; 49 a[cnt].x=x[i]+x[j]; 50 a[cnt].y=y[i]+y[j]; 51 a[cnt].len=sqr(x[i]-x[j])+sqr(y[i]-y[j]); 52 } 53 sort(a+1,a+cnt+1); 54 long long ans=0; 55 for (long long i=1;i<cnt;i++) 56 for (long long j=i+1;j<=cnt;j++) 57 if (a[i].x == a[j].x && a[i].y == a[j].y && a[i].len == a[j].len) 58 { 59 long long x1=x[a[j].f]-x[a[i].f]; 60 long long x2=x[a[j].t]-x[a[i].f]; 61 long long y1=y[a[j].f]-y[a[i].f]; 62 long long y2=y[a[j].t]-y[a[i].f]; 63 ans=max(ans,abs(x1*y2-x2*y1)); 64 } 65 else 66 break; 67 printf(LL "\n",ans); 68 return 0; 69 }
bzoj2342
manacher+set扫一遍,据说有O(n)的算法
1 #include <cstdio> 2 #include <algorithm> 3 #include <set> 4 5 using namespace std; 6 7 #define maxn 10000010 8 9 set <int> t; 10 set <int>::iterator it; 11 12 int n; 13 char a[maxn]; 14 int p[maxn],pos[maxn]; 15 16 inline int min(int a,int b) 17 { 18 return a < b ? a : b; 19 } 20 21 inline bool cmp(int a,int b) 22 { 23 return a-p[a] < b-p[b]; 24 } 25 26 inline void doit() 27 { 28 int mx=0,id=0; 29 for (int i=1;i<n;i++) 30 { 31 if (mx > i) 32 p[i]=min(p[(id<<1)-i],mx-i); 33 else 34 p[i]=1; 35 for (;a[i+p[i]] == a[i-p[i]];p[i]++); 36 if (i+p[i] > mx) 37 { 38 mx=i+p[i]; 39 id=i; 40 } 41 } 42 int size=0; 43 for (int i=2;i<=n;i+=2) 44 pos[++size]=i; 45 sort(pos+1,pos+size+1,cmp); 46 int now=1,ans=0; 47 for (int i=2;i<=n;i+=2) 48 { 49 while (now <= size && pos[now]-p[pos[now]] < i) 50 { 51 t.insert(pos[now]); 52 now++; 53 } 54 it=t.upper_bound(i+p[i]/2); 55 it--; 56 if (*it >= i && *it <= i+(p[i] >> 1)) 57 ans=max(ans,(*it-i)*2); 58 } 59 printf("%d\n",ans); 60 } 61 62 int main() 63 { 64 scanf("%d\n",&n); 65 for (int i=1;i<=n;i++) 66 { 67 a[(i<<1)-1]=getchar(); 68 a[(i<<1)]='#'; 69 } 70 n=(n<<1)-1; 71 doit(); 72 return 0; 73 }
bzoj2351
二维hash,矩阵模板的双倍经验,但是加强了数据,注意base的选取
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define base1 29 7 #define base2 31 8 #define maxn 1010 9 10 typedef unsigned int ull; 11 12 ull bit1[maxn],bit2[maxn]; 13 ull a[maxn][maxn],san[maxn*maxn],map[maxn][maxn]; 14 15 int main() 16 { 17 int m,n,l,r; 18 scanf("%d%d%d%d",&m,&n,&l,&r); 19 m^=n^=m^=n; 20 for (int i=1;i<=n;i++) 21 for (int j=1;j<=m;j++) 22 { 23 char ch; 24 while (ch=getchar(),ch != '0' && ch != '1'); 25 map[i][j]=ch-'0'; 26 if (map[i][j]) 27 map[i][j]=19; 28 else 29 map[i][j]=17; 30 } 31 bit1[0]=bit2[0]=1; 32 for (int i=1;i<=n;i++) 33 { 34 bit1[i]=bit1[i-1]*base1; 35 bit2[i]=bit2[i-1]*base2; 36 } 37 for (int i=1;i<=n;i++) 38 { 39 ull now_hash=0; 40 for (int j=1;j<=r;j++) 41 now_hash=now_hash*base1+map[i][j]; 42 a[i][r]=now_hash; 43 for (int j=r+1;j<=m;j++) 44 { 45 now_hash=now_hash*base1+map[i][j]; 46 now_hash-=map[i][j-r]*bit1[r]; 47 a[i][j]=now_hash; 48 } 49 } 50 int size=0; 51 for (int j=r+1;j<=m;j++) 52 { 53 ull now_hash=0; 54 for (int i=1;i<=l;i++) 55 now_hash=now_hash*base2+a[i][j]; 56 san[++size]=now_hash; 57 for (int i=l+1;i<=n;i++) 58 { 59 now_hash=now_hash*base2+a[i][j]; 60 now_hash-=a[i-l][j]*bit2[l]; 61 san[++size]=now_hash; 62 } 63 } 64 sort(san+1,san+size+1); 65 size=unique(san+1,san+size+1)-san-1; 66 int q; 67 scanf("%d",&q); 68 while (q--) 69 { 70 for (int i=1;i<=l;i++) 71 for (int j=1;j<=r;j++) 72 { 73 char ch; 74 while (ch=getchar(),ch != '0' && ch != '1'); 75 map[i][j]=ch-'0'; 76 if (map[i][j]) 77 map[i][j]=19; 78 else 79 map[i][j]=17; 80 } 81 ull hash=0; 82 for (int i=1;i<=l;i++) 83 { 84 ull now_hash=0; 85 for (int j=1;j<=r;j++) 86 now_hash=now_hash*base1+map[i][j]; 87 hash=hash*base2+now_hash; 88 } 89 int pos=lower_bound(san+1,san+size+1,hash)-san; 90 if (san[pos] == hash) 91 puts("1"); 92 else 93 puts("0"); 94 } 95 return 0; 96 }
bzoj2424
当年一直以为是DP,然后费用流直接过了
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1010 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow,dist,cost; 16 edge *next,*part; 17 }e[maxm],*head[maxn],*prev[maxn]; 18 19 int ne; 20 int q[maxn],d[maxn]; 21 bool flag[maxn]; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 inline bool spfa() 41 { 42 memset(d,0x3f,sizeof(d)); 43 memset(flag,0,sizeof(flag)); 44 int op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 flag[s]=1; 48 while (op != cls) 49 { 50 op=op == maxn-1 ? 0 : op+1; 51 int x=q[op]; 52 for (edge *p=head[x];p;p=p->next) 53 if (p->flow && d[p->to] > d[x]+p->cost) 54 { 55 d[p->to]=d[x]+p->cost; 56 prev[p->to]=p->part; 57 if (!flag[p->to]) 58 { 59 if (op != cls) 60 { 61 int now=op == maxn-1 ? 0 : op+1; 62 if (d[p->to] < d[q[now]]) 63 { 64 q[op]=p->to; 65 op=op == 0 ? maxn-1 : op-1; 66 } 67 else 68 { 69 cls=cls == maxn-1 ? 0 : cls+1; 70 q[cls]=p->to; 71 } 72 } 73 else 74 { 75 cls=cls == maxn-1 ? 0 : cls+1; 76 q[cls]=p->to; 77 } 78 flag[p->to]=1; 79 } 80 } 81 flag[x]=0; 82 } 83 return d[t] != inf; 84 } 85 86 inline int agument() 87 { 88 int f=inf,ans=0; 89 for (edge *p=prev[t];p;p=prev[p->to]) 90 f=min(f,p->part->flow); 91 for (edge *p=prev[t];p;p=prev[p->to]) 92 { 93 p->flow+=f; 94 p->part->flow-=f; 95 ans+=p->part->cost*f; 96 } 97 return ans; 98 } 99 100 inline int min_cost() 101 { 102 int ans=0; 103 while (spfa()) 104 ans+=agument(); 105 return ans; 106 } 107 108 int main() 109 { 110 int n,m,v; 111 scanf("%d%d%d",&n,&m,&v); 112 for (int i=1;i<n;i++) 113 add_edge(i,i+1,v,m); 114 for (int i=1;i<=n;i++) 115 { 116 int x; 117 scanf("%d",&x); 118 add_edge(i,t,x,0); 119 } 120 for (int i=1;i<=n;i++) 121 { 122 int x; 123 scanf("%d",&x); 124 add_edge(s,i,inf,x); 125 } 126 printf("%d\n",min_cost()); 127 return 0; 128 }
bzoj2426
想了很久的网络流,最后发现是贪心。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 55 7 #define maxm 50010 8 #define inf 0x3f3f3f3f 9 10 int c[maxn][maxm]; 11 int a[maxm],h[maxn],d[maxm],pos[maxm]; 12 13 inline void read(int &x) 14 { 15 char ch; 16 while (ch=getchar(),ch > '9' || ch < '0'); 17 x=ch-'0'; 18 while (ch=getchar(),ch <= '9' && ch >= '0') 19 x=(x<<3)+x+x+ch-'0'; 20 } 21 22 inline bool cmp(const int a,const int b) 23 { 24 return d[a] < d[b]; 25 } 26 27 int main() 28 { 29 int n,m,b,xx; 30 read(m); 31 read(b); 32 read(xx); 33 read(n); 34 for (int i=1;i<=m;i++) 35 read(a[i]); 36 for (int i=1;i<=n;i++) 37 read(h[i]); 38 for (int i=0;i<=n;i++) 39 for (int j=1;j<=m;j++) 40 read(c[i][j]); 41 int _min=inf,ans=0; 42 for (int i=1;i<=n;i++) 43 { 44 for (int j=1;j<=m;j++) 45 { 46 pos[j]=j; 47 d[j]=c[0][j]-c[i][j]; 48 } 49 sort(pos+1,pos+m+1,cmp); 50 int rest=b,sum=0; 51 for (int j=1;j<=m;j++) 52 { 53 int now=pos[j]; 54 if (a[now] <= rest) 55 { 56 rest-=a[now]; 57 sum+=c[0][now]*a[now]; 58 } 59 else 60 { 61 sum+=c[0][now]*rest; 62 rest=a[now]-rest; 63 sum+=c[i][now]*rest; 64 rest=0; 65 } 66 } 67 sum+=h[i]; 68 if (sum < _min) 69 { 70 _min=sum; 71 ans=i; 72 } 73 } 74 printf("%d\n",ans); 75 printf("%d\n",_min+xx); 76 return 0; 77 }
bzoj2431
DP,f[i][j]表示放到i了,当前有j对逆序对的数列的个数
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1010 7 #define mod 10000 8 9 int f[maxn][maxn],sum[maxn][maxn]; 10 11 int main() 12 { 13 int n,k; 14 scanf("%d%d",&n,&k); 15 for (int i=1;i<=n;i++) 16 { 17 f[i][1]=sum[i][1]=1; 18 for (int j=2;j<=k+1;j++) 19 { 20 f[i][j]=(sum[i-1][j]-sum[i-1][max(j-i,0)]+mod)%mod; 21 sum[i][j]=(sum[i][j-1]+f[i][j])%mod; 22 } 23 } 24 printf("%d\n",f[n][k+1]); 25 return 0; 26 }
bzoj2435
树形DFS
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1000010 7 8 struct edge 9 { 10 int to,dist; 11 edge *next; 12 }e[maxn<<1],*head[maxn]; 13 14 int ne=0; 15 int fa[maxn],w[maxn],size[maxn]; 16 17 inline void read(int &x) 18 { 19 char ch; 20 while (ch=getchar(),ch > '9' || ch < '0'); 21 x=ch-'0'; 22 while (ch=getchar(),ch <= '9' && ch >= '0') 23 x=(x<<3)+x+x+ch-'0'; 24 } 25 26 inline void add_edge(int from,int to,int dist) 27 { 28 e[ne].to=to; 29 e[ne].dist=dist; 30 e[ne].next=head[from]; 31 head[from]=&e[ne++]; 32 } 33 34 void dfs(int now) 35 { 36 size[now]=1; 37 for (edge *p=head[now];p;p=p->next) 38 if (p->to != fa[now]) 39 { 40 fa[p->to]=now; 41 w[p->to]=p->dist; 42 dfs(p->to); 43 size[now]+=size[p->to]; 44 } 45 } 46 47 int main() 48 { 49 int n; 50 read(n); 51 for (int i=1;i<n;i++) 52 { 53 int x,y,z; 54 read(x); 55 read(y); 56 read(z); 57 add_edge(x,y,z); 58 add_edge(y,x,z); 59 } 60 dfs(1); 61 long long ans=0; 62 for (int i=2;i<=n;i++) 63 ans+=(long long)abs(n-size[i]*2)*w[i]; 64 printf("%lld\n",ans); 65 return 0; 66 }
bzoj2436
让我想这个DP肯定想不出来。。。题读错了好几遍。。。具体题解百度吧
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 410 8 #define inf 0x3f3f3f3f 9 10 int b[maxn]; 11 int f[maxn][maxn],g[maxn][maxn],ans[maxn][maxn],num[maxn][maxn]; 12 int l[maxn],r[maxn]; 13 14 inline int max(int a,int b) 15 { 16 return a > b ? a : b; 17 } 18 19 inline int min(int a,int b) 20 { 21 return a < b ? a : b; 22 } 23 24 int main() 25 { 26 int n; 27 int size=0; 28 scanf("%d",&n); 29 for (int i=1;i<=n;i++) 30 { 31 scanf("%d%d",&l[i],&r[i]); 32 r[i]+=l[i]; 33 b[++size]=l[i]; 34 b[++size]=r[i]; 35 } 36 sort(b+1,b+size+1); 37 size=unique(b+1,b+size+1)-b-1; 38 for (int i=1;i<=n;i++) 39 { 40 l[i]=lower_bound(b+1,b+size+1,l[i])-b; 41 r[i]=lower_bound(b+1,b+size+1,r[i])-b; 42 } 43 for (int i=1;i<=size;i++) 44 for (int j=i;j<=size;j++) 45 for (int k=1;k<=n;k++) 46 if (l[k] >= i && r[k] <= j) 47 num[i][j]++; 48 for (int i=0;i<=size+1;i++) 49 for (int j=0;j<=size+1;j++) 50 f[i][j]=g[i][j]=-inf; 51 f[0][0]=0; 52 for (int i=1;i<=size;i++) 53 for (int j=i;j>=0;j--) 54 { 55 f[i][j]=f[i][j+1]; 56 for (int k=0;k<i;k++) 57 { 58 f[i][j]=max(f[i][j],f[k][j]+num[k][i]); 59 if (j >= num[k][i]) 60 f[i][j]=max(f[i][j],f[k][j-num[k][i]]); 61 } 62 } 63 g[size+1][0]=0; 64 for (int i=size;i;i--) 65 for (int j=size-i+1;j>=0;j--) 66 { 67 g[i][j]=g[i][j+1]; 68 for (int k=i+1;k<=size+1;k++) 69 { 70 g[i][j]=max(g[i][j],g[k][j]+num[i][k]); 71 if (j >= num[i][k]) 72 g[i][j]=max(g[i][j],g[k][j-num[i][k]]); 73 } 74 } 75 for (int i=1;i<=size;i++) 76 for (int j=i;j<=size;j++) 77 for (int x=0;x<=i;x++) 78 for (int y=0;y<=size-j+1;y++) 79 if (x+y <= n) 80 { 81 int now=min(x+y+num[i][j],f[i][x]+g[j][y]); 82 if (ans[i][j] < now) 83 ans[i][j]=now; 84 else 85 break; 86 } 87 else 88 break; 89 int now=0; 90 for (int i=1;i<=n;i++) 91 now=max(now,min(i,f[size][i])); 92 printf("%d\n",now); 93 for (int i=1;i<=n;i++) 94 { 95 now=0; 96 for (int j=1;j<=l[i];j++) 97 for (int k=r[i];k<=size;k++) 98 now=max(now,ans[j][k]); 99 printf("%d\n",now); 100 } 101 return 0; 102 }
bzoj2457
据说可以排序之后贪心,表示只能理解排序之后DP。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 200010 7 8 typedef pair <int,int> pii; 9 10 pii a[maxn]; 11 int _max[maxn],_min[maxn]; 12 int f[maxn][2]; 13 14 inline void read(int &x) 15 { 16 char ch; 17 bool flag=0; 18 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-')); 19 if (ch == '-') 20 flag=1; 21 else 22 x=ch-'0'; 23 while (ch=getchar(),ch <= '9' && ch >= '0') 24 x=(x<<3)+x+x+ch-'0'; 25 if (flag) 26 x=-x; 27 } 28 29 inline bool cmp(const pii a,const pii b) 30 { 31 return (a.first < b.first) || (a.first == b.first && a.second < b.second); 32 } 33 34 int main() 35 { 36 // freopen("1.in","r",stdin); 37 // freopen("1.out","w",stdout); 38 int n; 39 read(n); 40 for (int i=1;i<=n;i++) 41 { 42 read(a[i].first); 43 a[i].second=i; 44 } 45 sort(a+1,a+n+1,cmp); 46 a[0].first=a[1].first; 47 int cnt=1; 48 _min[cnt]=a[1].second; 49 for (int i=1;i<=n;i++) 50 if (a[i].first != a[i-1].first) 51 { 52 _max[cnt]=a[i-1].second; 53 cnt++; 54 _min[cnt]=a[i].second; 55 } 56 _max[cnt]=a[n].second; 57 f[1][0]=f[1][1]=1; 58 for (int i=2;i<=cnt;i++) 59 { 60 if (_min[i] < _max[i-1]) 61 f[i][0]=min(f[i-1][0]+1,f[i-1][1]); 62 else 63 f[i][0]=min(f[i-1][0],f[i-1][1]); 64 if (_max[i] > _min[i-1]) 65 f[i][1]=min(f[i-1][0],f[i-1][1])+1; 66 else 67 f[i][1]=min(f[i-1][0]+1,f[i-1][1]); 68 } 69 printf("%d\n",min(f[cnt][0],f[cnt][1])); 70 return 0; 71 }
bzoj2462
二维hash,据说可以KMP,又据说答案全是1可以过
#include <cstdio> #include <algorithm> using namespace std; #define base1 29 #define base2 31 #define maxn 1010 typedef unsigned int ull; ull bit1[maxn],bit2[maxn]; ull a[maxn][maxn],san[maxn*maxn],map[maxn][maxn]; int main() { int m,n,l,r; scanf("%d%d%d%d",&m,&n,&l,&r); m^=n^=m^=n; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { char ch; while (ch=getchar(),ch != '0' && ch != '1'); map[i][j]=ch-'0'; if (map[i][j]) map[i][j]=19; else map[i][j]=17; } bit1[0]=bit2[0]=1; for (int i=1;i<=n;i++) { bit1[i]=bit1[i-1]*base1; bit2[i]=bit2[i-1]*base2; } for (int i=1;i<=n;i++) { ull now_hash=0; for (int j=1;j<=r;j++) now_hash=now_hash*base1+map[i][j]; a[i][r]=now_hash; for (int j=r+1;j<=m;j++) { now_hash=now_hash*base1+map[i][j]; now_hash-=map[i][j-r]*bit1[r]; a[i][j]=now_hash; } } int size=0; for (int j=r+1;j<=m;j++) { ull now_hash=0; for (int i=1;i<=l;i++) now_hash=now_hash*base2+a[i][j]; san[++size]=now_hash; for (int i=l+1;i<=n;i++) { now_hash=now_hash*base2+a[i][j]; now_hash-=a[i-l][j]*bit2[l]; san[++size]=now_hash; } } sort(san+1,san+size+1); size=unique(san+1,san+size+1)-san-1; int q; scanf("%d",&q); while (q--) { for (int i=1;i<=l;i++) for (int j=1;j<=r;j++) { char ch; while (ch=getchar(),ch != '0' && ch != '1'); map[i][j]=ch-'0'; if (map[i][j]) map[i][j]=19; else map[i][j]=17; } ull hash=0; for (int i=1;i<=l;i++) { ull now_hash=0; for (int j=1;j<=r;j++) now_hash=now_hash*base1+map[i][j]; hash=hash*base2+now_hash; } int pos=lower_bound(san+1,san+size+1,hash)-san; if (san[pos] == hash) puts("1"); else puts("0"); } return 0; }
bzoj2463
我还能说什么好呢。。。这道题。。。
1 #include <cstdio> 2 3 int main() 4 { 5 int n; 6 while (~scanf("%d",&n)) 7 { 8 if (!n) 9 break; 10 if (n&1) 11 puts("Bob"); 12 else 13 puts("Alice"); 14 } 15 return 0; 16 }
bzoj2464
要不要那么裸的spfa。。。当年拿来练slf优化用的,手写双端循环队列的寂寞。。。
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 2500010 5 #define maxm 5000010 6 7 struct edge 8 { 9 int to,dist; 10 edge *next; 11 }e[maxm],*head[maxn]; 12 13 int ne=0; 14 int pos[510][510]; 15 int q[maxn],d[maxn]; 16 bool map[maxn],flag[maxn]; 17 18 inline void add_edge(int from,int to,int dist) 19 { 20 e[ne].to=to; 21 e[ne].dist=dist; 22 e[ne].next=head[from]; 23 head[from]=&e[ne++]; 24 } 25 26 inline int spfa(int s,int t) 27 { 28 int op=0,cls=1; 29 memset(d,0x3f,sizeof(d)); 30 memset(flag,0,sizeof(flag)); 31 q[1]=s; 32 d[s]=0; 33 flag[s]=1; 34 while (op != cls) 35 { 36 op=op == maxn-1 ? 0 : op+1; 37 int x=q[op]; 38 flag[x]=0; 39 for (edge *p=head[x];p;p=p->next) 40 { 41 if (d[x]+p->dist < d[p->to]) 42 { 43 d[p->to]=d[x]+p->dist; 44 if (!flag[p->to]) 45 { 46 if (op != cls) 47 { 48 int now=op == maxn-1 ? 0 : op+1; 49 if (d[p->to] < d[q[now]]) 50 { 51 q[op]=p->to; 52 op=op == 0 ? maxn-1 : op-1; 53 } 54 else 55 { 56 cls=cls == maxn-1 ? 0 : cls+1; 57 q[cls]=p->to; 58 } 59 } 60 else 61 { 62 cls=cls == maxn-1 ? 0 : cls+1; 63 q[cls]=p->to; 64 } 65 flag[p->to]=1; 66 } 67 } 68 } 69 } 70 return d[t]; 71 } 72 73 int main() 74 { 75 int n,m; 76 while (1) 77 { 78 scanf("%d%d",&n,&m); 79 if (!n && !m) 80 break; 81 for (int i=1;i<=n;i++) 82 for (int j=1;j<=m;j++) 83 pos[i][j]=(i-1)*m+j; 84 for (int i=1;i<=n;i++) 85 for (int j=1;j<=m;j++) 86 { 87 char ch; 88 while (ch=getchar(),ch != '@' && ch != '#'); 89 if (ch == '@') 90 map[pos[i][j]]=1; 91 else 92 map[pos[i][j]]=0; 93 } 94 ne=0; 95 memset(head,0x0,sizeof(head)); 96 for (int i=1;i<=n;i++) 97 for (int j=1;j<=m;j++) 98 { 99 if (i != 1) 100 add_edge(pos[i][j],pos[i-1][j],map[pos[i][j]] != map[pos[i-1][j]]); 101 if (i != n) 102 add_edge(pos[i][j],pos[i+1][j],map[pos[i][j]] != map[pos[i+1][j]]); 103 if (j != 1) 104 add_edge(pos[i][j],pos[i][j-1],map[pos[i][j]] != map[pos[i][j-1]]); 105 if (j != m) 106 add_edge(pos[i][j],pos[i][j+1],map[pos[i][j]] != map[pos[i][j+1]]); 107 } 108 int sx,sy,tx,ty; 109 scanf("%d%d%d%d",&sx,&sy,&tx,&ty); 110 sx++; 111 sy++; 112 tx++; 113 ty++; 114 printf("%d\n",spfa(pos[sx][sy],pos[tx][ty])); 115 } 116 return 0; 117 }
bzoj2465
太水了不想说了。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 210 7 8 int a[maxn]; 9 10 struct xxx 11 { 12 int v,val; 13 inline bool operator < (const xxx b) const 14 { 15 return val > b.val; 16 } 17 }b[maxn]; 18 19 inline bool cmp(const int a,const int b) 20 { 21 return a > b; 22 } 23 24 int main() 25 { 26 int n,m; 27 while (1) 28 { 29 scanf("%d%d",&n,&m); 30 if (n == 0 && m == 0) 31 break; 32 for (int i=1;i<=n;i++) 33 scanf("%d",&a[i]); 34 for (int i=1;i<=m;i++) 35 scanf("%d%d",&b[i].v,&b[i].val); 36 sort(a+1,a+n+1,cmp); 37 sort(b+1,b+m+1); 38 int nowa=1,nowb=1,ans=0,sum=0; 39 while (nowb <= m) 40 { 41 while (b[nowb].val < a[nowa] && nowa <= n) 42 nowa++; 43 if (nowa == n+1) 44 break; 45 while (b[nowb].v && nowa <= n) 46 { 47 sum++; 48 ans+=a[nowa]; 49 b[nowb].v--; 50 nowa++; 51 } 52 if (nowa == n+1) 53 break; 54 nowb++; 55 } 56 printf("%d %d\n",sum,ans); 57 } 58 return 0; 59 }
bzoj2467
推公式
1 #include <cstdio> 2 3 int main() 4 { 5 int _; 6 scanf("%d",&_); 7 while (_--) 8 { 9 int n,ans=4; 10 scanf("%d",&n); 11 ans*=n; 12 for (int i=1;i<n;i++) 13 (ans*=5)%=2007; 14 printf("%d\n",ans); 15 } 16 return 0; 17 }
bzoj2535
对于这种双倍经验我能说什么呢?
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 2010 8 #define maxm 10010 9 10 struct edge 11 { 12 int to; 13 edge *next; 14 }e[maxm],*head[maxn]; 15 16 int ne=0; 17 int cnt=0; 18 int q[maxn],ans[maxn],in[maxn]; 19 pair <int,int> a[maxn]; 20 bool check[maxn][maxn]; 21 bool flag[maxn]; 22 23 inline void add_edge(int from,int to) 24 { 25 e[ne].to=to; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 void dfs(int x) 31 { 32 flag[x]=1; 33 for (edge *p=head[x];p;p=p->next) 34 if (!flag[p->to]) 35 dfs(p->to); 36 q[++cnt]=x; 37 } 38 39 void dfs(int now,int x) 40 { 41 flag[x]=1; 42 check[now][x]=1; 43 for (edge *p=head[x];p;p=p->next) 44 if (!flag[p->to]) 45 dfs(now,p->to); 46 } 47 48 int main() 49 { 50 int n,m; 51 scanf("%d%d",&n,&m); 52 int x,y; 53 for (int i=1;i<=n;i++) 54 { 55 scanf("%d",&a[i].first); 56 a[i].second=i; 57 } 58 for (int i=1;i<=m;i++) 59 { 60 scanf("%d%d",&x,&y); 61 add_edge(y,x); 62 } 63 for (int i=1;i<=n;i++) 64 if (!flag[i]) 65 dfs(i); 66 for (int i=n;i;i--) 67 { 68 int x=q[i]; 69 for (edge *p=head[x];p;p=p->next) 70 a[p->to].first=min(a[p->to].first,a[x].first-1); 71 } 72 sort(a+1,a+n+1); 73 for (int i=1;i<=n;i++) 74 { 75 memset(flag,0,sizeof(flag)); 76 dfs(i,i); 77 printf("%d ",a[i].second); 78 } 79 puts(""); 80 for (int i=1;i<=n;i++) 81 { 82 int now=n; 83 for (int j=n;j;j--) 84 if (!check[i][a[j].second] && a[j].first >= now) 85 now--; 86 else 87 if (a[j].first < now) 88 break; 89 printf("%d ",now); 90 } 91 return 0; 92 }
bzoj2539
裸费用流。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1100 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow,cost; 16 edge *next,*part; 17 }e[maxm],*head[maxn],*prev[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 bool flag[maxn]; 22 23 inline void add(int from,int to,int flow,int cost) 24 { 25 e[ne].to=to; 26 e[ne].flow=flow; 27 e[ne].cost=cost; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow,int cost) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow,cost); 37 add(to,from,0,-cost); 38 } 39 40 41 inline bool spfa() 42 { 43 memset(d,0x80,sizeof(d)); 44 memset(flag,0,sizeof(flag)); 45 int op=0,cls=1; 46 q[1]=s; 47 d[s]=0; 48 flag[s]=1; 49 while (op != cls) 50 { 51 op=op == maxn-1 ? 0 : op+1; 52 int x=q[op]; 53 for (edge *p=head[x];p;p=p->next) 54 if (p->flow && d[p->to] < d[x]+p->cost) 55 { 56 d[p->to]=d[x]+p->cost; 57 prev[p->to]=p->part; 58 if (!flag[p->to]) 59 { 60 if (op != cls) 61 { 62 int now=op == maxn-1 ? 0 : op+1; 63 if (d[p->to] > d[q[now]]) 64 { 65 q[op]=p->to; 66 op=op == 0 ? maxn-1 : op-1; 67 } 68 else 69 { 70 cls=cls == maxn-1 ? 0 : cls+1; 71 q[cls]=p->to; 72 } 73 } 74 else 75 { 76 cls=cls == maxn-1 ? 0 : cls+1; 77 q[cls]=p->to; 78 } 79 flag[p->to]=1; 80 } 81 } 82 flag[x]=0; 83 } 84 return d[t] > -inf; 85 } 86 87 inline int agument() 88 { 89 int f=inf,ans=0; 90 for (edge *p=prev[t];p;p=prev[p->to]) 91 f=min(f,p->part->flow); 92 for (edge *p=prev[t];p;p=prev[p->to]) 93 { 94 p->flow+=f; 95 p->part->flow-=f; 96 ans+=p->part->cost*f; 97 } 98 return ans; 99 } 100 101 inline int max_cost() 102 { 103 int ans=0; 104 while (spfa()) 105 ans+=agument(); 106 return ans; 107 } 108 109 int range,n; 110 int x[maxn],y[maxn],l[maxn]; 111 char name[maxn][30]; 112 int map[maxn][maxn]; 113 114 inline int sqr(int x) 115 { 116 return x*x; 117 } 118 119 inline bool check(int a,int b) 120 { 121 int d=sqr(x[a]-x[b])+sqr(y[a]-y[b]); 122 if (d > range) 123 return 0; 124 if (x[a] == x[b]) 125 { 126 if (y[a] > y[b]) 127 swap(a,b); 128 for (int i=1;i<=2*n;i++) 129 if (i != a && i != b) 130 if (x[i] == x[a] && y[i] > y[a] && y[i] < y[b]) 131 return 0; 132 return 1; 133 } 134 if (x[a] > x[b]) 135 swap(a,b); 136 for (int i=1;i<=2*n;i++) 137 if (i != a && i != b) 138 if (x[i] > x[a] && x[i] < x[b]) 139 if ((y[b]-y[i])*(x[i]-x[a]) == (y[i]-y[a])*(x[b]-x[i])) 140 return 0; 141 return 1; 142 } 143 144 inline bool cmp(int a,int b) 145 { 146 if (l[a] != l[b]) 147 return 0; 148 for (int i=0;i<l[a];i++) 149 if (name[a][i] != name[b][i]) 150 return 0; 151 return 1; 152 } 153 154 inline bool cmp(int a,char *now) 155 { 156 int len=strlen(now); 157 if (len != l[a]) 158 return 0; 159 for (int i=0;i<len;i++) 160 if (name[a][i] != now[i]) 161 return 0; 162 return 1; 163 } 164 165 int main() 166 { 167 scanf("%d",&range); 168 range*=range; 169 scanf("%d",&n); 170 for (int i=1;i<=2*n;i++) 171 { 172 scanf("%d%d%s",&x[i],&y[i],name[i]); 173 l[i]=strlen(name[i]); 174 for (int j=0;j<l[i];j++) 175 if (name[i][j] >= 'A' && name[i][j] <= 'Z') 176 name[i][j]+=32; 177 } 178 char s1[maxn],s2[maxn]; 179 while (1) 180 { 181 scanf("%s",s1); 182 if (s1[0] == 'E' && s1[1] == 'n' && s1[2] == 'd' && s1[3] == '\0') 183 break; 184 scanf("%s",s2); 185 for (int i=0;s1[i];i++) 186 if (s1[i] >= 'A' && s1[i] <= 'Z') 187 s1[i]+=32; 188 for (int i=0;s2[i];i++) 189 if (s2[i] >= 'A' && s2[i] <= 'Z') 190 s2[i]+=32; 191 int l=0,r=0; 192 for (int i=1;i<=2*n;i++) 193 if (cmp(i,s1)) 194 { 195 l=i; 196 break; 197 } 198 for (int i=1;i<=2*n;i++) 199 if (cmp(i,s2)) 200 { 201 r=i; 202 break; 203 } 204 if (l > r) 205 swap(l,r); 206 int x; 207 scanf("%d",&x); 208 map[l][r]=x; 209 } 210 for (int i=1;i<=n;i++) 211 for (int j=n+1;j<=2*n;j++) 212 if (check(i,j)) 213 { 214 if (!map[i][j]) 215 map[i][j]=1; 216 add_edge(i,j,1,map[i][j]); 217 } 218 for (int i=1;i<=n;i++) 219 add_edge(s,i,1,0); 220 for (int i=n+1;i<=2*n;i++) 221 add_edge(i,t,1,0); 222 printf("%d\n",max_cost()); 223 return 0; 224 }
bzoj2565
双倍回文的双倍经验题,注意奇偶
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 #define maxn 200010 8 9 int n; 10 int a[maxn]; 11 char s[maxn]; 12 int p[maxn]; 13 int pos[maxn]; 14 15 inline bool cmp(int x,int y) 16 { 17 return x-p[x] < y-p[y]; 18 } 19 20 int main() 21 { 22 scanf("%s",s); 23 n=strlen(s); 24 if (n == 1) 25 { 26 printf("0\n"); 27 return 0; 28 } 29 for (int i=0;i<n;i++) 30 { 31 a[i*2+1]='#'; 32 a[i*2+2]=s[i]; 33 } 34 a[n*2+1]='#'; 35 n=2*n+1; 36 for (int i=1;i<=n;i++) 37 pos[i]=i; 38 int mx=0,id=0; 39 for (int i=1;i<=n;i++) 40 { 41 if (mx > i) 42 p[i]=min(p[2*id-i],mx-i); 43 else 44 p[i]=1; 45 for (;a[i+p[i]] == a[i-p[i]];p[i]++); 46 if (i+p[i] > mx) 47 { 48 mx=i+p[i]; 49 id=i; 50 } 51 } 52 sort(pos+1,pos+n+1,cmp); 53 int now=1,ans=0; 54 for (int i=1;i<=n;i++) 55 { 56 while (now <= n && pos[now]-p[pos[now]]+1 <= i+p[i]) 57 ans=max(ans,pos[now++]-i); 58 if (now > n) 59 break; 60 } 61 printf("%d\n",ans); 62 return 0; 63 }
bzoj2588
1146的不带修改的版本,可以每个结点维护到根的主席树
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn=100010; 7 8 struct Node 9 { 10 int size; 11 Node* s[2]; 12 }t[maxn*25],*root[maxn],null; 13 14 struct edge 15 { 16 int to; 17 edge *next; 18 }e[maxn<<1],*head[maxn]; 19 20 int n,m,K; 21 int ans=0; 22 int ne=0; 23 int a[maxn],b[maxn]; 24 int d[maxn],f[maxn][30]; 25 int q[maxn]; 26 27 inline void add_edge(int from,int to) 28 { 29 e[ne].to=to; 30 e[ne].next=head[from]; 31 head[from]=&e[ne++]; 32 } 33 34 inline void bfs() 35 { 36 int op=0,cls=1; 37 q[1]=1; 38 d[1]=1; 39 edge *p; 40 while (op != cls) 41 { 42 int x=q[++op]; 43 for (p=head[x];p;p=p->next) 44 if (!d[p->to]) 45 { 46 d[p->to]=d[x]+1; 47 f[p->to][0]=x; 48 q[++cls]=p->to; 49 } 50 } 51 } 52 53 inline void lca_pre() 54 { 55 for (K=1;1<<(K+1)<=n;K++); 56 for (int k=1;k<=K;k++) 57 for (int i=1;i<=n;i++) 58 if (d[i] >= 1<<k) 59 f[i][k]=f[f[i][k-1]][k-1]; 60 } 61 62 inline int lca_get(int x,int y) 63 { 64 if (d[x] < d[y]) 65 { 66 int t; 67 t=x,x=y,y=t; 68 } 69 while (d[x] != d[y]) 70 { 71 int k; 72 for (k=0;1<<(k+1)<=(d[x]-d[y]);k++); 73 x=f[x][k]; 74 } 75 while (x != y) 76 { 77 int k; 78 for (k=0;f[x][k+1]!=f[y][k+1];k++); 79 x=f[x][k]; 80 y=f[y][k]; 81 } 82 return x; 83 } 84 85 Node* build(Node* pre,int val,int l,int r) 86 { 87 Node* now=&t[ne++]; 88 now->s[0]=pre->s[0]; 89 now->s[1]=pre->s[1]; 90 now->size=pre->size+1; 91 if (l == r) 92 return now; 93 int mid=(l+r)>>1; 94 if (val <= mid) 95 now->s[0]=build(pre->s[0],val,l,mid); 96 else 97 now->s[1]=build(pre->s[1],val,mid+1,r); 98 return now; 99 } 100 101 int query(Node* x,Node* y,Node* lca,Node* flca,int l,int r,int k) 102 { 103 while (l != r) 104 { 105 int del=x->s[0]->size+y->s[0]->size-lca->s[0]->size-flca->s[0]->size; 106 int mid=(l+r)>>1; 107 if (k <= del) 108 { 109 r=mid; 110 x=x->s[0],y=y->s[0],lca=lca->s[0],flca=flca->s[0]; 111 } 112 else 113 { 114 k-=del; 115 l=mid+1; 116 x=x->s[1],y=y->s[1],lca=lca->s[1],flca=flca->s[1]; 117 } 118 } 119 return l; 120 } 121 122 int main() 123 { 124 null.s[0]=null.s[1]=&null; 125 null.size=0; 126 scanf("%d%d",&n,&m); 127 for (int i=1;i<=n;i++) 128 { 129 scanf("%d",a+i); 130 b[i]=a[i]; 131 } 132 sort(b+1,b+n+1); 133 int size=0; 134 b[0]=b[1]-1; 135 for (int i=1;i<=n;i++) 136 if (b[i] != b[i-1]) 137 b[++size]=b[i]; 138 for (int i=1;i<=n;i++) 139 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 140 int x,y,k; 141 for (int i=1;i<n;i++) 142 { 143 scanf("%d%d",&x,&y); 144 add_edge(x,y); 145 add_edge(y,x); 146 } 147 ne=0; 148 bfs(); 149 lca_pre(); 150 root[0]=&null; 151 for (int i=1;i<=n;i++) 152 { 153 x=q[i]; 154 root[x]=build(root[f[x][0]],a[x],1,n); 155 } 156 for (int i=1;i<m;i++) 157 { 158 scanf("%d%d%d",&x,&y,&k); 159 x^=ans; 160 int z=lca_get(x,y); 161 ans=b[query(root[x],root[y],root[z],root[f[z][0]],1,n,k)]; 162 printf("%d\n",ans); 163 } 164 scanf("%d%d%d",&x,&y,&k); 165 x^=ans; 166 int z=lca_get(x,y); 167 ans=b[query(root[x],root[y],root[z],root[f[z][0]],1,n,k)]; 168 printf("%d",ans); 169 return 0; 170 }
bzoj2631
lct+维护序列(bzoj1798),注意long long(出题人给的mod不良心)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 #define mod 51061 8 9 struct Node 10 { 11 long long sum,lazy_mul,lazy_add,size,v; 12 bool rot; 13 Node *par,*s[2]; 14 15 inline Node() 16 { 17 lazy_add=0; 18 sum=size=lazy_mul=v=1; 19 rot=0; 20 } 21 22 inline bool S() 23 { 24 return this == par->s[1]; 25 } 26 }t[maxn],null; 27 28 inline void _update(Node* now) 29 { 30 now->size=now->s[0]->size+now->s[1]->size+1; 31 now->sum=(now->s[0]->sum+now->s[1]->sum+now->v)%mod; 32 } 33 34 inline void _pushdown(Node* now) 35 { 36 if (now->rot) 37 { 38 swap(now->s[0],now->s[1]); 39 now->s[0]->rot^=1; 40 now->s[1]->rot^=1; 41 now->rot=0; 42 } 43 if (now->lazy_mul != 1) 44 { 45 long long mul=now->lazy_mul; 46 (now->s[0]->lazy_mul*=mul)%=mod; 47 (now->s[1]->lazy_mul*=mul)%=mod; 48 (now->s[0]->lazy_add*=mul)%=mod; 49 (now->s[1]->lazy_add*=mul)%=mod; 50 (now->s[0]->v*=mul)%=mod; 51 (now->s[1]->v*=mul)%=mod; 52 (now->s[0]->sum*=mul)%=mod; 53 (now->s[1]->sum*=mul)%=mod; 54 now->lazy_mul=1; 55 } 56 if (now->lazy_add) 57 { 58 long long add=now->lazy_add; 59 (now->s[0]->lazy_add+=add)%=mod; 60 (now->s[1]->lazy_add+=add)%=mod; 61 (now->s[0]->v+=add)%=mod; 62 (now->s[1]->v+=add)%=mod; 63 (now->s[0]->sum+=add*now->s[0]->size)%=mod; 64 (now->s[1]->sum+=add*now->s[1]->size)%=mod; 65 now->lazy_add=0; 66 } 67 null.sum=0; 68 } 69 70 inline bool root(Node* now) 71 { 72 return now != now->par->s[0] && now != now->par->s[1]; 73 } 74 75 inline void _rot(Node* now) 76 { 77 Node* p=now->par; 78 long long l=now->S(),r=!l; 79 (p->s[l]=now->s[r])->par=p; 80 if (root(p)) 81 now->par=p->par; 82 else 83 (p->par->s[p->S()]=now)->par=p->par; 84 (now->s[r]=p)->par=now; 85 _update(p); 86 _update(now); 87 } 88 89 void relax(Node* now) 90 { 91 if (!root(now)) 92 relax(now->par); 93 _pushdown(now); 94 } 95 96 inline void _splay(Node* now) 97 { 98 relax(now); 99 while (!root(now)) 100 { 101 if (root(now->par)) 102 { 103 _rot(now); 104 return; 105 } 106 if (now->par->S() == now->S()) 107 { 108 _rot(now->par); 109 _rot(now); 110 } 111 else 112 { 113 _rot(now); 114 _rot(now); 115 } 116 } 117 } 118 119 inline Node* access(Node* p) 120 { 121 Node* q=&null; 122 for (;p!=&null;q=p,p=p->par) 123 { 124 _splay(p); 125 p->s[1]=q; 126 if (q != &null) 127 q->par=p; 128 } 129 return q; 130 } 131 132 inline void set_root(Node* now) 133 { 134 access(now); 135 _splay(now); 136 now->rot^=1; 137 _pushdown(now); 138 } 139 140 inline void link(Node* p,Node* q) 141 { 142 set_root(p); 143 p->par=q; 144 } 145 146 inline void cut(Node* p,Node* q) 147 { 148 set_root(p); 149 access(q); 150 _splay(q); 151 p->par=q->s[0]=&null; 152 } 153 154 inline void add(Node* p,Node* q,long long val) 155 { 156 set_root(p); 157 access(q); 158 _splay(q); 159 (q->lazy_add+=val)%=mod; 160 (q->v+=val)%=mod; 161 (q->sum+=val*q->size)%=mod; 162 } 163 164 inline void mul(Node* p,Node* q,long long val) 165 { 166 set_root(p); 167 access(q); 168 _splay(q); 169 (q->lazy_mul*=val)%=mod; 170 (q->lazy_add*=val)%=mod; 171 (q->sum*=val)%=mod; 172 (q->v*=val)%=mod; 173 } 174 175 inline long long query(Node* p,Node* q) 176 { 177 set_root(p); 178 access(q); 179 _splay(q); 180 _update(q); 181 return q->sum; 182 } 183 184 void travel(Node* now) 185 { 186 _pushdown(now); 187 if (now->s[0] != &null) 188 travel(now->s[0]); 189 printf("%lld %lld %lld\n",now-t,now->v,now->sum); 190 if (now->s[1] != &null) 191 travel(now->s[1]); 192 } 193 194 struct edge 195 { 196 long long to; 197 edge *next; 198 }e[maxn<<1],*head[maxn]; 199 200 long long ne=0; 201 long long q[maxn],fa[maxn]; 202 203 inline void add_edge(long long from,long long to) 204 { 205 e[ne].to=to; 206 e[ne].next=head[from]; 207 head[from]=&e[ne++]; 208 } 209 210 inline void bfs() 211 { 212 long long op=0,cls=1; 213 fa[1]=0; 214 q[1]=1; 215 while (op != cls) 216 { 217 long long x=q[++op]; 218 for (edge *p=head[x];p;p=p->next) 219 if (p->to != fa[x]) 220 { 221 fa[p->to]=x; 222 q[++cls]=p->to; 223 } 224 } 225 } 226 227 int main() 228 { 229 null.s[0]=null.s[1]=null.par=&null; 230 null.size=null.sum=null.v=null.lazy_mul=0; 231 long long n,q; 232 scanf("%lld%lld",&n,&q); 233 for (long long i=1;i<n;i++) 234 { 235 long long x,y; 236 scanf("%lld%lld",&x,&y); 237 add_edge(x,y); 238 add_edge(y,x); 239 } 240 bfs(); 241 for (long long i=1;i<=n;i++) 242 { 243 if (fa[i]) 244 t[i].par=&t[fa[i]]; 245 else 246 t[i].par=&null; 247 t[i].s[0]=t[i].s[1]=&null; 248 } 249 while (q--) 250 { 251 char s[2]; 252 long long x,y,z,w; 253 scanf("%s",s); 254 if (s[0] == '+') 255 { 256 scanf("%lld%lld%lld",&x,&y,&z); 257 add(&t[x],&t[y],z); 258 } 259 if (s[0] == '-') 260 { 261 scanf("%lld%lld%lld%lld",&x,&y,&z,&w); 262 cut(&t[x],&t[y]); 263 link(&t[z],&t[w]); 264 } 265 if (s[0] == '*') 266 { 267 scanf("%lld%lld%lld",&x,&y,&z); 268 mul(&t[x],&t[y],z); 269 } 270 if (s[0] == '/') 271 { 272 scanf("%lld%lld",&x,&y); 273 printf("%lld\n",query(&t[x],&t[y])); 274 } 275 } 276 return 0; 277 }
bzoj2653
二分+可持久化线段树(对于每个数维护一颗线段树,然后求最大字段和)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 20010 7 8 struct Node 9 { 10 int lmax,rmax,sum; 11 Node *s[2]; 12 }t[maxn*100],*root[maxn],null; 13 14 int ne=0; 15 int q[4]; 16 17 inline void _update(Node* now) 18 { 19 now->lmax=max(now->s[0]->lmax,now->s[0]->sum+now->s[1]->lmax); 20 now->rmax=max(now->s[1]->rmax,now->s[1]->sum+now->s[0]->rmax); 21 now->sum=now->s[0]->sum+now->s[1]->sum; 22 } 23 24 Node* update(Node* pre,int l,int r,int pos,int add) 25 { 26 Node* now=&t[ne++]; 27 now->s[0]=pre->s[0]; 28 now->s[1]=pre->s[1]; 29 if (l == r) 30 { 31 now->lmax=now->rmax=now->sum=add; 32 return now; 33 } 34 int mid=(l+r)>>1; 35 if (pos <= mid) 36 now->s[0]=update(pre->s[0],l,mid,pos,add); 37 else 38 now->s[1]=update(pre->s[1],mid+1,r,pos,add); 39 _update(now); 40 return now; 41 } 42 43 Node* build(int l,int r) 44 { 45 Node* now=&t[ne++]; 46 if (l == r) 47 { 48 now->lmax=now->rmax=now->sum=1; 49 now->s[0]=now->s[1]=&null; 50 return now; 51 } 52 int mid=(l+r)>>1; 53 now->s[0]=build(l,mid); 54 now->s[1]=build(mid+1,r); 55 _update(now); 56 return now; 57 } 58 59 int query_sum(Node* now,int l,int r,int L,int R) 60 { 61 if (l == L && r == R) 62 return now->sum; 63 int mid=(l+r)>>1; 64 if (R <= mid) 65 return query_sum(now->s[0],l,mid,L,R); 66 else 67 if (L > mid) 68 return query_sum(now->s[1],mid+1,r,L,R); 69 else 70 return query_sum(now->s[0],l,mid,L,mid)+query_sum(now->s[1],mid+1,r,mid+1,R); 71 } 72 73 int query_l(Node* now,int l,int r,int L,int R) 74 { 75 if (l == L && r == R) 76 return now->lmax; 77 int mid=(l+r)>>1; 78 if (R <= mid) 79 return query_l(now->s[0],l,mid,L,R); 80 else 81 if (L > mid) 82 return query_l(now->s[1],mid+1,r,L,R); 83 else 84 return max(query_l(now->s[0],l,mid,L,mid),query_sum(now->s[0],l,mid,L,mid)+max(query_l(now->s[1],mid+1,r,mid+1,R),0)); 85 } 86 87 int query_r(Node* now,int l,int r,int L,int R) 88 { 89 if (l == L && r == R) 90 return now->rmax; 91 int mid=(l+r)>>1; 92 if (R <= mid) 93 return query_r(now->s[0],l,mid,L,R); 94 else 95 if (L > mid) 96 return query_r(now->s[1],mid+1,r,L,R); 97 else 98 return max(query_r(now->s[1],mid+1,r,mid+1,R),query_sum(now->s[1],mid+1,r,mid+1,R)+max(query_r(now->s[0],l,mid,L,mid),0)); 99 } 100 101 inline bool check(int l,int r,int now) 102 { 103 int sum=0; 104 if (q[1]+1 <= q[2]-1) 105 sum+=query_sum(root[now],l,r,q[1]+1,q[2]-1); 106 sum+=query_r(root[now],l,r,q[0],q[1]); 107 sum+=query_l(root[now],l,r,q[2],q[3]); 108 return sum >= 0; 109 } 110 111 pair <int ,int > a[maxn]; 112 113 inline void read(int &x) 114 { 115 char ch; 116 while (ch=getchar(),ch > '9' || ch < '0'); 117 x=ch-'0'; 118 while (ch=getchar(),ch <= '9' && ch >= '0') 119 x=(x<<3)+x+x+ch-'0'; 120 } 121 122 int main() 123 { 124 null.s[0]=null.s[1]=&null; 125 int n; 126 read(n); 127 for (int i=0;i<n;i++) 128 { 129 read(a[i].first); 130 a[i].second=i; 131 } 132 sort(a,a+n); 133 root[0]=build(0,n-1); 134 for (int i=1;i<n;i++) 135 root[i]=update(root[i-1],0,n-1,a[i-1].second,-1); 136 int ans=0; 137 int _; 138 read(_); 139 while (_--) 140 { 141 for (int i=0;i<4;i++) 142 { 143 q[i]=0; 144 read(q[i]); 145 (q[i]+=ans)%=n; 146 } 147 sort(q,q+4); 148 int l=-1,r=n; 149 while (l < r) 150 { 151 int mid=(l+r)>>1; 152 if (check(0,n-1,mid)) 153 { 154 ans=mid; 155 l=mid+1; 156 } 157 else 158 r=mid; 159 } 160 ans=a[ans].first; 161 printf("%d\n",ans); 162 } 163 return 0; 164 }
bzoj2659
考虑几何意义
#include <cstdio> int main(){int p,q;scanf("%d%d",&p,&q);printf("%lld\n",(long long)(p+(p==q))/2*(q/2));}
bzoj2660
类似于二进制的思路DP
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 90 7 8 long long fib[maxn]; 9 long long f[maxn][2]; 10 11 int main() 12 { 13 fib[1]=1; 14 fib[2]=2; 15 for (int i=3;i<=88;i++) 16 fib[i]=fib[i-1]+fib[i-2]; 17 long long n; 18 scanf("%lld",&n); 19 int now[maxn],cnt=0; 20 for (int i=88;i;i--) 21 if (fib[i] <= n) 22 { 23 n-=fib[i]; 24 now[++cnt]=i; 25 } 26 reverse(now+1,now+cnt+1); 27 f[1][1]=1; 28 f[1][0]=(now[1]-1)>>1; 29 for (int i=2;i<=cnt;i++) 30 { 31 f[i][1]=f[i-1][0]+f[i-1][1]; 32 f[i][0]=(now[i]-now[i-1]-1)/2*f[i-1][1]+(now[i]-now[i-1])/2*f[i-1][0]; 33 } 34 printf("%lld\n",f[cnt][0]+f[cnt][1]); 35 return 0; 36 }
bzoj2661
应该可以直接KM的,太弱不会KM,就只有先BFS染色然后费用流了
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define maxn 2020 9 #define maxm 1000010 10 #define inf 0x3f3f3f3f 11 12 struct edge 13 { 14 int to,flow,cost; 15 edge *next,*part; 16 }e[maxm],*head[maxn],*prev[maxn]; 17 18 int flow=0; 19 int s=0,t=maxn-1; 20 int ne=0; 21 int d[maxn],q[maxn]; 22 bool flag[maxn]; 23 24 inline bool spfa() 25 { 26 memset(d,-1,sizeof(d)); 27 memset(flag,0,sizeof(flag)); 28 int op=0,cls=1; 29 q[1]=s; 30 d[s]=0; 31 flag[s]=1; 32 while (op != cls) 33 { 34 op=op == maxn-1 ? 0 : op+1; 35 int x=q[op]; 36 for (edge *p=head[x];p;p=p->next) 37 if (p->flow && d[p->to] < d[x]+p->cost) 38 { 39 d[p->to]=d[x]+p->cost; 40 prev[p->to]=p->part; 41 if (!flag[p->to]) 42 { 43 if (op != cls) 44 { 45 int now=op == maxn-1 ? 0 : op+1; 46 if (d[p->to] > d[q[now]]) 47 { 48 q[op]=p->to; 49 op=op == 0 ? maxn-1 : op-1; 50 } 51 else 52 { 53 cls=cls == maxn-1 ? 0 : cls+1; 54 q[cls]=p->to; 55 } 56 } 57 else 58 { 59 cls=cls == maxn-1 ? 0 : cls+1; 60 q[cls]=p->to; 61 } 62 flag[p->to]=1; 63 } 64 } 65 flag[x]=0; 66 } 67 return d[t] != -1; 68 } 69 70 inline int agument() 71 { 72 int f=inf,ans=0; 73 for (edge *p=prev[t];p;p=prev[p->to]) 74 f=min(f,p->part->flow); 75 flow+=f; 76 for (edge *p=prev[t];p;p=prev[p->to]) 77 { 78 p->flow+=f; 79 p->part->flow-=f; 80 ans+=p->part->cost*f; 81 } 82 return ans; 83 } 84 85 inline int max_cost() 86 { 87 int ans=0; 88 while (spfa()) 89 ans+=agument(); 90 return ans; 91 } 92 93 inline void add(int from,int to,int flow,int cost) 94 { 95 e[ne].to=to; 96 e[ne].flow=flow; 97 e[ne].cost=cost; 98 e[ne].next=head[from]; 99 head[from]=&e[ne++]; 100 } 101 102 inline void add_edge(int from,int to,int flow,int cost) 103 { 104 e[ne].part=&e[ne+1]; 105 e[ne+1].part=&e[ne]; 106 add(from,to,flow,cost); 107 add(to,from,0,-cost); 108 } 109 110 bool vis[maxn]; 111 int col[maxn]; 112 113 inline void bfs(int s) 114 { 115 int op=0,cls=1; 116 q[1]=s; 117 vis[s]=1; 118 if (col[s] == -1) 119 col[s]=0; 120 while (op != cls) 121 { 122 int x=q[++op]; 123 for (edge *p=head[x];p;p=p->next) 124 { 125 if (!vis[p->to]) 126 { 127 col[p->to]=col[x]^1; 128 q[++cls]=p->to; 129 vis[p->to]=1; 130 } 131 } 132 } 133 } 134 135 int main() 136 { 137 int l,r; 138 scanf("%d%d",&l,&r); 139 memset(col,-1,sizeof(col)); 140 for (int i=l+1;i<=r;i++) 141 for (int j=l;j<=i-1;j++) 142 { 143 int now=i*i-j*j; 144 int check=(int)sqrt(now+0.5); 145 if (check*check == now && __gcd(now,j) == 1) 146 { 147 flag[i]=flag[j]=1; 148 add_edge(i,j,1,0); 149 add_edge(j,i,1,0); 150 } 151 } 152 for (int i=l;i<=r;i++) 153 if (flag[i] && !vis[i]) 154 bfs(i); 155 ne=0; 156 memset(head,0x0,sizeof(head)); 157 for (int i=l+1;i<=r;i++) 158 for (int j=l;j<=i-1;j++) 159 { 160 int now=i*i-j*j; 161 int check=(int)sqrt(now+0.5); 162 if (check*check == now && __gcd(now,j) == 1) 163 if (!col[i]) 164 add_edge(i,j,1,0); 165 else 166 add_edge(j,i,1,0); 167 } 168 for (int i=l;i<=r;i++) 169 { 170 if (col[i] == 0) 171 add_edge(s,i,1,i); 172 if (col[i] == 1) 173 add_edge(i,t,1,i); 174 } 175 int ans=max_cost(); 176 printf("%d %d\n",flow,ans); 177 return 0; 178 }
bzoj2697
神级贪心。。。一直在想怎么优化DP来着。。。果然还是太弱了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1010 7 8 int a[maxn]; 9 10 inline bool cmp(const int a,const int b) 11 { 12 return a > b; 13 } 14 15 int main() 16 { 17 int n,k; 18 scanf("%d%d",&n,&k); 19 for (int i=1;i<=k;i++) 20 scanf("%d",&a[i]); 21 sort(a+1,a+k+1,cmp); 22 if ((k<<1) > n) 23 k=n>>1; 24 int ans=0; 25 for (int i=1;i<=k;i++) 26 ans+=a[i]*(n-2*i+1); 27 printf("%d\n",ans); 28 return 0; 29 }
bzoj2711(已隐藏)
推一下这个式子,然后就发现可以怎么乱搞一下,然后就是一个背包
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 210 5 6 bool f[maxn][maxn*maxn]; 7 int a[maxn],x[maxn],y[maxn]; 8 9 inline int abs(int x) 10 { 11 return x >= 0 ? x : -x; 12 } 13 14 int main() 15 { 16 int ans=0,n; 17 scanf("%d",&n); 18 for (int i=1;i<=n;i++) 19 { 20 scanf("%d%d",&x[i],&y[i]); 21 ans-=x[i]*x[i]+y[i]*y[i]; 22 } 23 f[0][0]=1; 24 int _max=0; 25 for (int i=1;i<=n;i++) 26 { 27 _max+=x[i]; 28 for (int j=0;j<=_max;j++) 29 f[i][j]|=f[i-1][abs(j-x[i])]|f[i-1][j+x[i]]; 30 } 31 for (int i=0;i<=_max;i++) 32 if (f[n][i]) 33 { 34 ans+=i*i; 35 break; 36 } 37 memset(f,0,sizeof(f)); 38 f[0][0]=1; 39 _max=0; 40 for (int i=1;i<=n;i++) 41 { 42 _max+=y[i]; 43 for (int j=0;j<=_max;j++) 44 f[i][j]|=f[i-1][abs(j-y[i])]|f[i-1][j+y[i]]; 45 } 46 for (int i=0;i<=_max;i++) 47 if (f[n][i]) 48 { 49 ans+=i*i; 50 break; 51 } 52 printf("%d.00\n",ans>>1); 53 return 0; 54 }
bzoj2718(已隐藏)
1143的双倍经验
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 510 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 #define s 0 11 #define t maxn-1 12 13 struct edge 14 { 15 int to,flow; 16 edge *next,*part; 17 }e[maxm],*head[maxn]; 18 19 int ne=0; 20 int q[maxn],d[maxn]; 21 bool map[maxn][maxn]; 22 bool flag[maxn]; 23 24 inline void add(int from,int to,int flow) 25 { 26 e[ne].to=to; 27 e[ne].flow=flow; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow); 37 add(to,from,0); 38 } 39 40 inline void add_edge(int from,int to) 41 { 42 e[ne].to=to; 43 e[ne].next=head[from]; 44 head[from]=&e[ne++]; 45 } 46 47 inline bool bfs() 48 { 49 int op=0,cls=1; 50 memset(d,-1,sizeof(d)); 51 q[1]=s; 52 d[s]=0; 53 while (op != cls) 54 { 55 int x=q[++op]; 56 for (edge *p=head[x];p;p=p->next) 57 if (p->flow && d[p->to] == -1) 58 { 59 q[++cls]=p->to; 60 d[p->to]=d[x]+1; 61 } 62 } 63 return ~d[t]; 64 } 65 66 int dfs(int now,int now_flow) 67 { 68 if (now == t) 69 return now_flow; 70 int out=now_flow; 71 for (edge *p=head[now];p;p=p->next) 72 if (p->flow && d[p->to] == d[now]+1 && out) 73 { 74 int f=dfs(p->to,min(p->flow,out)); 75 p->flow-=f; 76 p->part->flow+=f; 77 out-=f; 78 } 79 if (out == now_flow) 80 d[now]=-1; 81 return now_flow-out; 82 } 83 84 inline int dinic() 85 { 86 int ans=0; 87 while (bfs()) 88 ans+=dfs(s,inf); 89 return ans; 90 } 91 92 inline void bfs(int now) 93 { 94 memset(flag,0,sizeof(flag)); 95 int op=0,cls=1; 96 q[1]=now; 97 flag[now]=1; 98 while (op != cls) 99 { 100 int x=q[++op]; 101 for (edge *p=head[x];p;p=p->next) 102 if (!flag[p->to]) 103 { 104 q[++cls]=p->to; 105 map[now][p->to]=1; 106 flag[p->to]=1; 107 } 108 } 109 } 110 111 int main() 112 { 113 int n,m; 114 scanf("%d%d",&n,&m); 115 for (int i=1;i<=m;i++) 116 { 117 int x,y; 118 scanf("%d%d",&x,&y); 119 add_edge(x,y); 120 } 121 for (int i=1;i<=n;i++) 122 bfs(i); 123 memset(head,0,sizeof(head)); 124 ne=0; 125 for (int i=1;i<=n;i++) 126 for (int j=1;j<=n;j++) 127 if (map[i][j]) 128 add_edge(i,j+n,1); 129 for (int i=1;i<=n;i++) 130 { 131 add_edge(s,i,1); 132 add_edge(i+n,t,1); 133 } 134 printf("%d\n",n-dinic()); 135 return 0; 136 }
bzoj2729
排列组合+高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #ifdef unix 11 #define ll "%lld" 12 #else 13 #define ll "%I64d" 14 #endif 15 class wkint { 16 private: 17 long long a[1510]; 18 int len; 19 public: 20 wkint(); 21 wkint(int t); 22 void read(); 23 void print(); 24 wkint operator + (const wkint &t) const; 25 wkint operator - (const wkint &t) const; 26 wkint operator * (const wkint &t) const; 27 wkint operator * (const int &t) const; 28 wkint operator ^ (const int &t) const; 29 wkint operator / (const int &t) const; 30 int operator % (const int &t) const; 31 bool operator < (const wkint &t) const; 32 bool operator > (const wkint &t) const; 33 bool operator == (const wkint &t) const; 34 bool operator != (const wkint &t) const; 35 }; 36 37 wkint::wkint() { 38 len = 1; 39 memset(a, 0, sizeof(a)); 40 } 41 wkint::wkint(int t) { 42 len = 1; 43 a[1] = t; 44 } 45 void wkint::read() { 46 string tmp; 47 cin >> tmp; 48 int lenT = tmp.length(); 49 len = (lenT + 7) / 8; 50 int ptr = len, now = 0; 51 for (int i = 0; i < lenT; i ++) { 52 now *= 10; now += (int)(tmp[i] - '0'); 53 if (!((lenT - i - 1) % 8)) { 54 a[ptr] = now; 55 now = 0; 56 ptr --; 57 } 58 } 59 } 60 void wkint::print() { 61 printf(ll, a[len]); 62 for (int i = len - 1; i >= 1; i --) { 63 int ws = (int)log10((long double)(a[i] + 1)) + 1; 64 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 65 printf(ll, a[i]); 66 } 67 printf("\n"); 68 } 69 wkint wkint::operator + (const wkint &t) const { 70 wkint res; 71 int maxlen = max(t.len, len); 72 for (int i = 1; i <= maxlen; i ++) { 73 res.a[i] += a[i] + t.a[i]; 74 if (res.a[i] >= 100000000) { 75 res.a[i + 1] += res.a[i] / 100000000; 76 res.a[i] %= 100000000; 77 } 78 } 79 if (res.a[maxlen + 1]) maxlen ++; 80 res.len = maxlen; 81 return res; 82 } 83 wkint wkint::operator - (const wkint &t) const { 84 wkint res; 85 int maxlen = max(t.len, len); 86 for (int i = 1; i <= maxlen; i ++) { 87 res.a[i] += a[i] - t.a[i]; 88 if (res.a[i] < 0) { 89 res.a[i + 1] -= 1; 90 res.a[i] += 100000000; 91 } 92 } 93 while (!res.a[maxlen]) maxlen --; 94 res.len = maxlen; 95 return res; 96 } 97 wkint wkint::operator * (const wkint &t) const { 98 wkint res; 99 int maxlen = t.len + len - 1; 100 for (int i = 1; i <= len; i ++) 101 for (int j = 1; j <= t.len; j ++) { 102 res.a[i + j - 1] += a[i] * t.a[j]; 103 } 104 for (int i = 1; i <= maxlen; i ++) 105 if (res.a[i] > 100000000) { 106 res.a[i + 1] += res.a[i] / 100000000; 107 res.a[i] %= 100000000; 108 } 109 if (res.a[maxlen + 1]) maxlen ++; 110 res.len = maxlen; 111 return res; 112 } 113 wkint wkint::operator * (const int &t) const { 114 wkint res; 115 res.len = len; 116 for (int i = 1; i <= len; i ++) { 117 res.a[i] += a[i] * t; 118 if (res.a[i] > 100000000) { 119 res.a[i + 1] += res.a[i] / 100000000; 120 res.a[i] %= 100000000; 121 } 122 } 123 if (res.a[res.len + 1]) res.len ++; 124 return res; 125 } 126 wkint wkint::operator ^ (const int &t) const { 127 wkint res = wkint(1), tmp; 128 int now = t; 129 memcpy(tmp.a, a, sizeof(a)); 130 tmp.len = len; 131 while (now) { 132 if (now & 1) res = res * tmp; 133 tmp = tmp * tmp; 134 now >>= 1; 135 } 136 return res; 137 } 138 wkint wkint::operator / (const int &t) const { 139 wkint res; 140 long long now = 0; 141 res.len = len; 142 for (int i = len; i >= 1; i --) { 143 now *= 100000000, now += a[i]; 144 if (now < t) { 145 res.a[i] = 0; 146 } else { 147 res.a[i] = now / t; 148 now %= t; 149 } 150 } 151 while (!res.a[res.len]) res.len --; 152 return res; 153 } 154 int wkint::operator % (const int &t) const { 155 long long now = 0; 156 for (int i = len; i >= 1; i --) { 157 now *= 100000000, now += a[i]; 158 now %= t; 159 } 160 return (int)now; 161 } 162 bool wkint::operator < (const wkint &t) const { 163 if (len < t.len) return true; 164 if (len > t.len) return false; 165 for (int i = len; i >= 1; i --) 166 if (a[i] < t.a[i]) { 167 return true; 168 } else if (a[i] > t.a[i]) { 169 return false; 170 } 171 return false; 172 } 173 bool wkint::operator > (const wkint &t) const { 174 if (len > t.len) return true; 175 if (len < t.len) return false; 176 for (int i = len; i >= 1; i --) 177 if (a[i] > t.a[i]) { 178 return true; 179 } else if (a[i] < t.a[i]) { 180 return false; 181 } 182 return false; 183 } 184 bool wkint::operator == (const wkint &t) const { 185 if (t.len != len) return false; 186 for (int i = 1; i <= len; i ++) 187 if (a[i] != t.a[i]) { 188 return false; 189 } 190 return true; 191 } 192 bool wkint::operator != (const wkint &t) const { 193 if (t.len != len) return true; 194 for (int i = 1; i <= len; i ++) 195 if (a[i] != t.a[i]) { 196 return true; 197 } 198 return false; 199 } 200 201 int main() 202 { 203 int n,m; 204 scanf("%d%d",&n,&m); 205 wkint ans1=1; 206 wkint ans2=1; 207 for (int i=1;i<=n;i++) 208 ans1=ans1*i; 209 ans2=ans1*2; 210 ans1=ans1*(n+1); 211 ans1=ans1*n; 212 for (int i=n+4-m;i<=n+3;i++) 213 ans1=ans1*i; 214 ans2=ans2*(n+1); 215 ans2=ans2*m; 216 for (int i=n+4-m;i<=n+2;i++) 217 ans2=ans2*i; 218 ans1=ans1+ans2; 219 ans1.print(); 220 return 0; 221 }
bzoj2733
启发式合并平衡树。。。明明我写的是错的怎么就A了呢。。。真是一阵淡淡的忧伤(正解应该需要并查集)
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 int size,v,num; 8 Node* s[2]; 9 }t[maxn*55],*root[maxn],null; 10 11 int ne=0; 12 13 inline void _update(Node* now) 14 { 15 now->size=now->s[0]->size+now->s[1]->size+1; 16 } 17 18 inline void _rot(Node* &now,int l) 19 { 20 int r=!l; 21 Node* s=now->s[l]; 22 now->s[l]=s->s[r]; 23 s->s[r]=now; 24 s->size=now->size; 25 _update(now); 26 now=s; 27 } 28 29 void _maintain(Node* &now,int l) 30 { 31 int r=!l; 32 if (now->s[l]->s[l]->size > now->s[r]->size) 33 _rot(now,l); 34 else 35 { 36 if (now->s[l]->s[r]->size > now->s[r]->size) 37 { 38 _rot(now->s[l],r); 39 _rot(now,l); 40 } 41 else 42 return; 43 } 44 _maintain(now->s[0],0); 45 _maintain(now->s[1],1); 46 _maintain(now,0); 47 _maintain(now,1); 48 } 49 50 inline Node* new_Node() 51 { 52 Node* now=&t[ne++]; 53 now->s[0]=now->s[1]=&null; 54 return now; 55 } 56 57 void insert(Node* &now,int v,int num) 58 { 59 if (now == &null) 60 { 61 now=new_Node(); 62 now->v=v; 63 now->size=1; 64 now->num=num; 65 return; 66 } 67 now->size++; 68 if (v < now->v) 69 insert(now->s[0],v,num); 70 else 71 insert(now->s[1],v,num); 72 // _maintain(now,v >= now->v); 73 } 74 75 inline int select(Node* now,int v) 76 { 77 while (v) 78 { 79 if (now == &null) 80 return -1; 81 if (now->s[0]->size+1 == v) 82 return now->num; 83 if (v <= now->s[0]->size) 84 now=now->s[0]; 85 else 86 { 87 v-=now->s[0]->size+1; 88 now=now->s[1]; 89 } 90 } 91 } 92 93 int cnt; 94 int a[maxn],b[maxn]; 95 96 void travel(Node* now) 97 { 98 if (now->s[0] != &null) 99 travel(now->s[0]); 100 a[++cnt]=now->v; 101 b[cnt]=now->num; 102 if (now->s[1] != &null) 103 travel(now->s[1]); 104 } 105 106 inline void merge(int x,int y) 107 { 108 if (root[x] == root[y]) 109 return; 110 if (root[x]->size > root[y]->size) 111 x^=y^=x^=y; 112 cnt=0; 113 travel(root[x]); 114 for (int i=1;i<=cnt;i++) 115 insert(root[y],a[i],b[i]); 116 root[x]=root[y]; 117 } 118 119 void test_travel(Node* now) 120 { 121 if (now->s[0] != &null) 122 test_travel(now->s[0]); 123 printf("%d ",now->v); 124 if (now->s[1] != &null) 125 test_travel(now->s[1]); 126 } 127 128 int main() 129 { 130 int n,m; 131 scanf("%d%d",&n,&m); 132 null.s[0]=null.s[1]=&null; 133 null.v=null.size=0; 134 for (int i=1;i<=n;i++) 135 { 136 root[i]=&null; 137 int x; 138 scanf("%d",&x); 139 insert(root[i],x,i); 140 } 141 for (int i=1;i<=m;i++) 142 { 143 int x,y; 144 scanf("%d%d",&x,&y); 145 merge(x,y); 146 } 147 int _; 148 scanf("%d",&_); 149 while (_--) 150 { 151 char s[2]; 152 int x,y; 153 scanf("%s%d%d",s,&x,&y); 154 if (x == 0 || y == 0) 155 continue; 156 if (s[0] == 'B') 157 merge(x,y); 158 else 159 printf("%d\n",select(root[x],y)); 160 } 161 return 0; 162 }
bzoj2743
离线+树状数组
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 1000010 7 8 struct query 9 { 10 int l,r,num; 11 }q[maxn]; 12 13 int n,m; 14 int bit[maxn]; 15 16 inline void read(int &x) 17 { 18 char ch; 19 while (ch=getchar(),ch > '9' || ch < '0'); 20 x=ch-'0'; 21 while (ch=getchar(),ch <= '9' && ch >= '0') 22 x=(x<<3)+x+x+ch-'0'; 23 } 24 25 inline void bit_update(int now,int add) 26 { 27 if (!now) 28 return; 29 for (;now<=n;now+=now & -now) 30 bit[now]+=add; 31 } 32 33 inline int ask(int x) 34 { 35 int ans=0; 36 for (;x>0;x-=x & -x) 37 ans+=bit[x]; 38 return ans; 39 } 40 41 int a[maxn],next[maxn],now[maxn],sum[maxn],ans[maxn]; 42 43 inline bool cmp(const query a,const query b) 44 { 45 return a.l < b.l; 46 } 47 48 int main() 49 { 50 int c; 51 read(n); 52 read(c); 53 read(m); 54 for (int i=1;i<=n;i++) 55 read(a[i]); 56 for (int i=1;i<=m;i++) 57 { 58 read(q[i].l); 59 read(q[i].r); 60 q[i].num=i; 61 } 62 sort(q+1,q+m+1,cmp); 63 for (int i=1;i<=n;i++) 64 { 65 if (now[a[i]]) 66 next[now[a[i]]]=i; 67 now[a[i]]=i; 68 } 69 for (int i=1;i<=n;i++) 70 { 71 sum[a[i]]++; 72 if (sum[a[i]] == 2) 73 bit_update(i,1); 74 } 75 int now_q=1; 76 for (int i=1;i<=n;i++) 77 { 78 while (q[now_q].l == i && now_q <= m) 79 { 80 ans[q[now_q].num]=ask(q[now_q].r); 81 now_q++; 82 } 83 if (now_q > m) 84 break; 85 bit_update(next[i],-1); 86 bit_update(next[next[i]],1); 87 } 88 for (int i=1;i<=m;i++) 89 printf("%d\n",ans[i]); 90 return 0; 91 }
bzoj2746
orz lyd神犇的hash乱搞大法,加了个读入优化又不小心rank1了,掉RP啊。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1000010 8 #define maxl 10000010 9 #define mod 1000000007 10 11 typedef unsigned long long ull; 12 13 int size=0; 14 ull b[maxl],bit[maxn]; 15 int ans[maxn],ans_bit[maxn]; 16 int head[maxn],tail[maxn]; 17 char s[maxl<<1],str[maxn],st[maxn]; 18 19 inline int query(int ax,int ay,int bx,int by) 20 { 21 int len=0; 22 char ch; 23 ull now=0; 24 for (;ay-len && by-len && (ch=s[head[ax]+ay-len-1]) == s[head[bx]+by-len-1];len++) 25 now+=(ch-'a'+1)*bit[len]; 26 for (int i=len-1;i>=0;i--) 27 { 28 int pos=lower_bound(b+1,b+size+1,now)-b; 29 if (b[pos] == now) 30 { 31 len=i+1; 32 break; 33 } 34 now-=(ull)(s[head[ax]+ay-i-1]-'a'+1)*bit[i]; 35 } 36 return len; 37 } 38 39 inline void read(int &x) 40 { 41 x=0; 42 char ch; 43 while (ch=getchar(),ch > '9' || ch < '0'); 44 x=ch-'0'; 45 while (ch=getchar(),ch <= '9' && ch >= '0') 46 x=(x<<3)+x+x+ch-'0'; 47 } 48 49 int main() 50 { 51 int n; 52 read(n); 53 char ch; 54 int _max=0; 55 for (int i=1;i<=n;i++) 56 { 57 scanf("%s",str); 58 int len=strlen(str); 59 if (i == 1) 60 ch=str[0]; 61 for (int j=1;j<len;j++) 62 if (str[j] != ch) 63 { 64 ch=0; 65 break; 66 } 67 st[i]=str[0]; 68 head[i]=tail[i-1]+1; 69 tail[i]=tail[i-1]+len; 70 ull now=0; 71 for (int j=0;j<len;j++) 72 { 73 s[head[i]+j]=str[j]; 74 now=now*27LL+str[j]-'a'+1; 75 b[++size]=now; 76 } 77 _max=max(_max,len); 78 } 79 sort(b+1,b+size+1); 80 size=unique(b+1,b+size+1)-b-1; 81 bit[0]=1; 82 for (int i=1;i<=_max;i++) 83 bit[i]=bit[i-1]*27LL; 84 if (ch) 85 { 86 ans_bit[0]=1; 87 for (int i=1;i<=_max;i++) 88 { 89 ans[i]=((ull)ans[i-1]*26LL+ch-'a')%mod; 90 ans_bit[i]=((ull)ans_bit[i-1]*26LL)%mod; 91 } 92 } 93 int m; 94 read(m); 95 for (int i=1;i<=m;i++) 96 { 97 int ax,ay,bx,by; 98 read(ax); 99 read(ay); 100 read(bx); 101 read(by); 102 int now=0; 103 if (ch) 104 { 105 if (ax == bx && ay == by) 106 now=(ans[ay-1]+(ull)(st[ax]-'a')*ans_bit[ay-1])%mod; 107 else 108 now=ans[min(ay-(st[ax] != ch),by-(st[bx] != ch))]; 109 } 110 else 111 { 112 int len=query(ax,ay,bx,by); 113 for (int j=ay-len+1;j<=ay;j++) 114 now=((ull)now*26LL+s[head[ax]+j-1]-'a')%mod; 115 } 116 printf("%d\n",now); 117 } 118 return 0; 119 }
bzoj2748
水水的DP
1 #include <cstdio> 2 3 #define maxn 55 4 #define maxp 1010 5 6 int n,be,max; 7 bool f[maxn][maxp]; 8 9 int main() 10 { 11 scanf("%d%d%d",&n,&be,&max); 12 f[0][be]=1; 13 for (int i=1;i<=n;i++) 14 { 15 int x; 16 scanf("%d",&x); 17 for (int j=0;j<=max;j++) 18 { 19 if (j >= x && f[i-1][j-x]) 20 f[i][j]=1; 21 if (j+x <= max && f[i-1][j+x]) 22 f[i][j]=1; 23 } 24 } 25 int ans=-1; 26 for (int i=max;i>=0;i--) 27 if (f[n][i]) 28 { 29 ans=i; 30 break; 31 } 32 printf("%d\n",ans); 33 return 0; 34 }
bzoj2749
考虑每个数会转化出来多少个2,注意初始没有2的话需要ans++
1 #include <cstdio> 2 3 #ifdef unix 4 #define LL "%lld" 5 #else 6 #define LL "%I64d" 7 #endif 8 9 #define maxp 100010 10 11 int size=0; 12 long long f[maxp]; 13 int prime[maxp]; 14 bool flag[maxp]; 15 16 inline void prime_pre() 17 { 18 for (int i=2;i<maxp;i++) 19 if (!flag[i]) 20 { 21 prime[++size]=i; 22 for (int j=2;i*j < maxp;j++) 23 flag[i*j]=1; 24 } 25 } 26 27 inline void read(int &x) 28 { 29 char ch; 30 while (ch=getchar(),ch > '9' || ch < '0'); 31 x=ch-'0'; 32 while (ch=getchar(),ch <= '9' && ch >= '0') 33 x=(x<<3)+x+x+ch-'0'; 34 } 35 36 int main() 37 { 38 //freopen("alien.in","r",stdin); 39 //freopen("alien.out","w",stdout); 40 prime_pre(); 41 f[0]=f[1]=0; 42 f[2]=1; 43 flag[1]=1; 44 for (int i=3;i<maxp;i++) 45 if (!flag[i]) 46 f[i]=f[i-1]; 47 else 48 { 49 for (int j=1;j<=size;j++) 50 if (i % prime[j] == 0) 51 { 52 f[i]=f[i/prime[j]]+f[prime[j]]; 53 break; 54 } 55 } 56 int _,n,x,y; 57 read(_); 58 while (_--) 59 { 60 long long ans=0; 61 bool flag2=0; 62 read(n); 63 for (int i=1;i<=n;i++) 64 { 65 read(x); 66 read(y); 67 if (x == 2) 68 flag2=1; 69 ans+=(long long)f[x]*y; 70 } 71 if (!flag2) 72 ans++; 73 printf(LL "\n",ans); 74 } 75 return 0; 76 }
bzoj2751
确实是容易题。。。对于不能取的数减掉,然后快速幂一下就好了
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 #define mod 1000000007LL 8 9 #ifdef unix 10 #define LL "%lld" 11 #else 12 #define LL "%I64d" 13 #endif 14 15 int n,m,k; 16 int x[maxn],y[maxn],pos[maxn]; 17 long long now,ans=1; 18 19 inline bool cmp(int a,int b) 20 { 21 if (x[a] == x[b]) 22 return y[a] < y[b]; 23 return x[a] < x[b]; 24 } 25 26 inline long long calc(long long a,int b) 27 { 28 long long ans=1,wk=a; 29 while (b) 30 { 31 if (b&1) 32 (ans*=wk)%=mod; 33 (wk*=wk)%=mod; 34 b>>=1; 35 } 36 return ans; 37 } 38 39 int main() 40 { 41 scanf("%d%d%d",&n,&m,&k); 42 for (int i=1;i<=k;i++) 43 { 44 scanf("%d%d",&x[i],&y[i]); 45 pos[i]=i; 46 } 47 sort(pos+1,pos+k+1,cmp); 48 now=(long long)n*(n+1)/2; 49 now%=mod; 50 x[pos[0]]=x[pos[1]]; 51 y[pos[0]]=0; 52 long long p=now-y[pos[1]]; 53 if (p < 0) 54 p+=mod; 55 int size=1; 56 for (int i=2;i<=k;i++) 57 { 58 if (x[pos[i]] != x[pos[i-1]]) 59 { 60 (ans*=p)%=mod; 61 p=now-y[pos[i]]; 62 if (p < 0) 63 p+=mod; 64 size++; 65 } 66 else 67 if (y[pos[i]] != y[pos[i-1]]) 68 { 69 p-=y[pos[i]]; 70 if (p < 0) 71 p+=mod; 72 } 73 } 74 (ans*=p)%=mod; 75 ans*=calc(now,m-size); 76 ans%=mod; 77 printf(LL "\n",ans); 78 return 0; 79 }
bzoj2752
考虑每条线段被覆盖的次数,线段树即可
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 struct Node 9 { 10 long long c0,c1,c2,s0,s1,s2,lazy; 11 }t[maxn<<2]; 12 13 inline void _update(long long rt) 14 { 15 t[rt].s0=t[rt<<1].s0+t[rt<<1|1].s0; 16 t[rt].s1=t[rt<<1].s1+t[rt<<1|1].s1; 17 t[rt].s2=t[rt<<1].s2+t[rt<<1|1].s2; 18 } 19 20 inline void _pushdown(long long rt) 21 { 22 if (t[rt].lazy) 23 { 24 long long add=t[rt].lazy; 25 t[rt].lazy=0; 26 t[rt<<1].lazy+=add; 27 t[rt<<1|1].lazy+=add; 28 t[rt<<1].s0+=add*t[rt<<1].c0; 29 t[rt<<1|1].s0+=add*t[rt<<1|1].c0; 30 t[rt<<1].s1+=add*t[rt<<1].c1; 31 t[rt<<1|1].s1+=add*t[rt<<1|1].c1; 32 t[rt<<1].s2+=add*t[rt<<1].c2; 33 t[rt<<1|1].s2+=add*t[rt<<1|1].c2; 34 } 35 } 36 37 void build(long long l,long long r,long long rt) 38 { 39 if (l == r) 40 { 41 t[rt].c0=1; 42 t[rt].c1=l; 43 t[rt].c2=l*l; 44 return; 45 } 46 long long mid=(l+r)>>1; 47 build(l,mid,rt<<1); 48 build(mid+1,r,rt<<1|1); 49 t[rt].c0=r-l+1; 50 t[rt].c1=t[rt<<1].c1+t[rt<<1|1].c1; 51 t[rt].c2=t[rt<<1].c2+t[rt<<1|1].c2; 52 } 53 54 void insert(long long l,long long r,long long rt,long long L,long long R,long long add) 55 { 56 if (l == L && r == R) 57 { 58 t[rt].lazy+=add; 59 t[rt].s0+=t[rt].c0*add; 60 t[rt].s1+=t[rt].c1*add; 61 t[rt].s2+=t[rt].c2*add; 62 return; 63 } 64 _pushdown(rt); 65 long long mid=(l+r)>>1; 66 if (R <= mid) 67 insert(l,mid,rt<<1,L,R,add); 68 else 69 if (L > mid) 70 insert(mid+1,r,rt<<1|1,L,R,add); 71 else 72 { 73 insert(l,mid,rt<<1,L,mid,add); 74 insert(mid+1,r,rt<<1|1,mid+1,R,add); 75 } 76 _update(rt); 77 } 78 79 long long query(long long l,long long r,long long rt,long long L,long long R) 80 { 81 if (l >= L && r <= R) 82 return -t[rt].s2+(L+R)*t[rt].s1+(-R*L+R-L+1)*t[rt].s0; 83 _pushdown(rt); 84 long long mid=(l+r)>>1; 85 if (R <= mid) 86 return query(l,mid,rt<<1,L,R); 87 else 88 if (L > mid) 89 return query(mid+1,r,rt<<1|1,L,R); 90 else 91 return query(l,mid,rt<<1,L,R)+query(mid+1,r,rt<<1|1,L,R); 92 } 93 94 int main() 95 { 96 long long n,_; 97 scanf("%lld%lld",&n,&_); 98 n--; 99 build(1,n,1); 100 while (_--) 101 { 102 char s[2]; 103 long long x,y,z; 104 scanf("%s%lld%lld",s,&x,&y); 105 y--; 106 if (s[0] == 'C') 107 { 108 scanf("%lld",&z); 109 insert(1,n,1,x,y,z); 110 } 111 else 112 { 113 long long ans=query(1,n,1,x,y),sum=(y-x+1)*(y-x+2)/2; 114 long long d=__gcd(ans,sum); 115 printf("%lld/%lld\n",ans/d,sum/d); 116 } 117 } 118 return 0; 119 }
bzoj2753
改一下mst排序的cmp即可。。。不知道怎么证明
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 #define maxm 1000010 8 9 struct edge 10 { 11 int from,to,dist; 12 edge *next; 13 }e[maxm<<1],*head[maxn]; 14 15 int ne=0; 16 int h[maxn],q[maxn],f[maxn],r[maxn],flag[maxn]; 17 18 inline void read(int &x) 19 { 20 char ch; 21 while (ch=getchar(),ch > '9' || ch < '0'); 22 x=ch-'0'; 23 while (ch=getchar(),ch <= '9' && ch >= '0') 24 x=(x<<3)+x+x+ch-'0'; 25 } 26 27 inline void add_edge(int from,int to,int dist) 28 { 29 e[ne].from=from; 30 e[ne].to=to; 31 e[ne].dist=dist; 32 e[ne].next=head[from]; 33 head[from]=&e[ne++]; 34 } 35 36 inline int bfs() 37 { 38 int op=0,cls=1,ans=1; 39 q[1]=1; 40 flag[1]=1; 41 while (op <= cls) 42 { 43 int x=q[++op]; 44 for (edge *p=head[x];p;p=p->next) 45 if (!flag[p->to]) 46 { 47 flag[p->to]=1; 48 q[++cls]=p->to; 49 ans++; 50 } 51 } 52 return ans; 53 } 54 55 inline bool cmp(const edge a,const edge b) 56 { 57 if (h[a.to] == h[b.to]) 58 return a.dist < b.dist; 59 return h[a.to] > h[b.to]; 60 } 61 62 int find(int x) 63 { 64 if (f[x] == x) 65 return x; 66 return f[x]=find(f[x]); 67 } 68 69 inline void _union(int x,int y) 70 { 71 if (r[x] <= r[y]) 72 { 73 f[x]=y; 74 r[y]+=r[x]; 75 } 76 else 77 { 78 f[y]=x; 79 r[x]+=r[y]; 80 } 81 } 82 83 int main() 84 { 85 int n,m; 86 read(n); 87 read(m); 88 for (int i=1;i<=n;i++) 89 read(h[i]); 90 for (int i=1;i<=m;i++) 91 { 92 int x,y,z; 93 read(x); 94 read(y); 95 read(z); 96 if (h[x] >= h[y]) 97 add_edge(x,y,z); 98 if (h[y] >= h[x]) 99 add_edge(y,x,z); 100 } 101 int cnt=bfs(); 102 printf("%d ",cnt); 103 sort(e,e+ne,cmp); 104 for (int i=1;i<=n;i++) 105 { 106 f[i]=i; 107 r[i]=1; 108 } 109 long long ans=0; 110 int sum=0; 111 for (int i=0;i<ne;i++) 112 { 113 if ((!flag[e[i].from]) || (!flag[e[i].to])) 114 continue; 115 int x=find(e[i].from),y=find(e[i].to); 116 if (x != y) 117 { 118 ans+=e[i].dist; 119 _union(x,y); 120 sum++; 121 } 122 if (sum == cnt-1) 123 break; 124 } 125 printf("%lld\n",ans); 126 return 0; 127 }
bzoj2754
当年曾经想写后缀数组版(不会fail树太弱了)的正解(O(nlogn+mlogn)没记错的话是这个复杂度),然后手贱还写了主席树,一晚上+一上午没调出来,然后怒删代码写了个O(nm)的,然后就A了
1 #include <cstdio> 2 3 #define maxn 300010 4 5 int n,m,len=-1; 6 int a[maxn],sa[maxn],num[maxn]; 7 int q[maxn],ql[maxn]; 8 int top,sta[maxn]; 9 int sum[maxn]; 10 bool flag[maxn]; 11 12 inline void read(int &x) 13 { 14 char ch; 15 while (ch=getchar(),(ch > '9' || ch < '0') && ch != '-'); 16 bool flag=0; 17 if (ch == '-') 18 { 19 flag=1; 20 x=0; 21 } 22 else 23 x=ch-'0'; 24 while (ch=getchar(),ch <= '9' && ch >= '0') 25 x=(x<<3)+x+x+ch-'0'; 26 if (flag) 27 x=-x; 28 } 29 30 inline int min(int a,int b) 31 { 32 return a < b ? a : b; 33 } 34 35 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 36 37 inline int cmp(int *r,int a,int b,int l) 38 {return r[a]==r[b]&&r[a+l]==r[b+l];} 39 40 inline void da(int *r,int *sa,int n,int m) 41 { 42 int i,j,p,*x=wa,*y=wb,*t; 43 for(i=0;i<m;i++) ws[i]=0; 44 for(i=0;i<n;i++) ws[x[i]=r[i]]++; 45 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 46 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 47 for(j=1,p=1;p<n;j*=2,m=p) 48 { 49 for(p=0,i=n-j;i<n;i++) y[p++]=i; 50 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 51 for(i=0;i<n;i++) wv[i]=x[y[i]]; 52 for(i=0;i<m;i++) ws[i]=0; 53 for(i=0;i<n;i++) ws[wv[i]]++; 54 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 55 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; 56 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 57 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 58 } 59 return; 60 } 61 62 int rank[maxn],height[maxn]; 63 64 inline void calheight(int *r,int *sa,int n) 65 { 66 int i,j,k=0; 67 for(i=1;i<=n;i++) rank[sa[i]]=i; 68 for(i=0;i<n;height[rank[i++]]=k) 69 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 70 return; 71 } 72 73 inline int get_ans(int pos,int val) 74 { 75 int ans=0; 76 top=0; 77 for (int i=pos-1;i>=0;i--) 78 { 79 if (height[i+1] < val) 80 break; 81 if (!flag[num[sa[i]]] && num[sa[i]]) 82 { 83 sum[num[sa[i]]]++; 84 ans++; 85 flag[num[sa[i]]]=1; 86 sta[++top]=num[sa[i]]; 87 } 88 } 89 for (int i=pos+1;i<=len;i++) 90 { 91 if (height[i] < val) 92 break; 93 if (!flag[num[sa[i]]] && num[sa[i]]) 94 { 95 sum[num[sa[i]]]++; 96 ans++; 97 flag[num[sa[i]]]=1; 98 sta[++top]=num[sa[i]]; 99 } 100 } 101 while (top) 102 { 103 flag[sta[top]]=0; 104 top--; 105 } 106 return ans; 107 } 108 109 int main() 110 { 111 int n,m; 112 read(n); 113 read(m); 114 for (int i=1;i<=n;i++) 115 { 116 int l; 117 read(l); 118 for (int j=len+1;j<=len+l;j++) 119 { 120 read(a[j]); 121 num[j]=i; 122 } 123 len+=l; 124 a[++len]=10001; 125 read(l); 126 for (int j=len+1;j<=len+l;j++) 127 { 128 read(a[j]); 129 num[j]=i; 130 } 131 len+=l; 132 a[++len]=10001; 133 } 134 for (int i=1;i<=m;i++) 135 { 136 q[i]=len+1; 137 read(ql[i]); 138 for (int j=len+1;j<=len+ql[i];j++) 139 read(a[j]); 140 len+=ql[i]; 141 a[++len]=10001; 142 } 143 da(a,sa,len+1,11000); 144 calheight(a,sa,len); 145 for (int i=1;i<=m;i++) 146 printf("%d\n",get_ans(rank[q[i]],ql[i])); 147 for (int i=1;i<n;i++) 148 printf("%d ",sum[i]); 149 printf("%d\n",sum[n]); 150 return 0; 151 }
bzoj2756
分奇偶,然后(二分)网络流
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 2010 8 #define maxm 1000010 9 #define s 0 10 #define t maxn-1 11 #define inf 0x3f3f3f3f3f3fLL 12 13 const long long fx[]={0,1,0,-1}; 14 const long long fy[]={1,0,-1,0}; 15 16 struct edge 17 { 18 long long to,flow; 19 edge *next,*part; 20 }e[maxm],*head[maxn]; 21 22 long long ne=0; 23 long long d[maxn],q[maxn]; 24 25 inline void add(long long from,long long to,long long flow) 26 { 27 e[ne].to=to; 28 e[ne].flow=flow; 29 e[ne].next=head[from]; 30 head[from]=&e[ne++]; 31 } 32 33 inline void add_edge(long long from,long long to,long long flow) 34 { 35 e[ne].part=&e[ne+1]; 36 e[ne+1].part=&e[ne]; 37 add(from,to,flow); 38 add(to,from,0); 39 } 40 41 inline bool bfs() 42 { 43 memset(d,-1,sizeof(d)); 44 long long op=0,cls=1; 45 q[1]=s; 46 d[s]=0; 47 while (op != cls) 48 { 49 long long x=q[++op]; 50 for (edge *p=head[x];p;p=p->next) 51 if (p->flow && d[p->to] == -1) 52 { 53 d[p->to]=d[x]+1; 54 q[++cls]=p->to; 55 } 56 } 57 return ~d[t]; 58 } 59 60 long long dfs(long long now,long long now_flow) 61 { 62 if (now == t) 63 return now_flow; 64 long long out=now_flow; 65 for (edge *p=head[now];p;p=p->next) 66 if (p->flow && d[p->to] == d[now]+1 && out) 67 { 68 long long f=dfs(p->to,min(p->flow,out)); 69 p->flow-=f; 70 p->part->flow+=f; 71 out-=f; 72 } 73 if (out == now_flow) 74 d[now]=-1; 75 return now_flow-out; 76 } 77 78 inline long long dinic() 79 { 80 long long ans=0; 81 while (bfs()) 82 ans+=dfs(s,inf); 83 return ans; 84 } 85 86 long long n,m; 87 long long map[50][50]; 88 long long pos[50][50]; 89 90 inline void dinic_pre(long long limit) 91 { 92 memset(head,0x0,sizeof(head)); 93 ne=0; 94 for (long long i=1;i<=n;i++) 95 for (long long j=1;j<=m;j++) 96 if ((i+j-1)&1) 97 for (long long k=0;k<4;k++) 98 { 99 long long x=i+fx[k],y=j+fy[k]; 100 if (x >= 1 && x <= n && y >= 1 && y <= m) 101 add_edge(pos[i][j],pos[x][y],inf); 102 } 103 for (long long i=1;i<=n;i++) 104 for (long long j=1;j<=m;j++) 105 if ((i+j-1)&1) 106 add_edge(s,pos[i][j],limit-map[i][j]); 107 else 108 add_edge(pos[i][j],t,limit-map[i][j]); 109 } 110 111 inline void doit() 112 { 113 long long _max=0; 114 long long sum1=0,sum2=0; 115 scanf("%lld%lld",&n,&m); 116 long long now_cnt=0; 117 for (long long i=1;i<=n;i++) 118 for (long long j=1;j<=m;j++) 119 { 120 scanf("%lld",&map[i][j]); 121 _max=max(_max,map[i][j]); 122 pos[i][j]=++now_cnt; 123 if ((i+j-1)&1) 124 sum1+=map[i][j]; 125 else 126 sum2+=map[i][j]; 127 } 128 if ((m*n)&1) 129 { 130 long long x=sum1-sum2; 131 if (x < _max) 132 { 133 puts("-1"); 134 return; 135 } 136 dinic_pre(x); 137 long long ans=0; 138 for (long long i=1;i<=n;i++) 139 for (long long j=1;j<=m;j++) 140 ans+=x-map[i][j]; 141 if (ans&1) 142 { 143 puts("-1"); 144 return; 145 } 146 ans>>=1; 147 long long now=dinic(); 148 if (now == ans) 149 printf("%lld\n",now); 150 else 151 puts("-1"); 152 } 153 else 154 { 155 if (sum1 != sum2) 156 { 157 puts("-1"); 158 return; 159 } 160 long long ans=0; 161 long long l=_max-1,r=0x3f3f3f3f*2; 162 while (l < r) 163 { 164 long long mid=(l+r)>>1; 165 if (mid < _max) 166 { 167 l=mid+1; 168 continue; 169 } 170 dinic_pre(mid); 171 long long now=dinic(); 172 long long cnt=0; 173 for (long long i=1;i<=n;i++) 174 for (long long j=1;j<=m;j++) 175 cnt+=mid-map[i][j]; 176 cnt>>=1; 177 if (now == cnt) 178 { 179 ans=now; 180 r=mid; 181 } 182 else 183 l=mid+1; 184 } 185 printf("%lld\n",ans); 186 } 187 } 188 189 int main() 190 { 191 long long _; 192 scanf("%lld",&_); 193 while (_--) 194 doit(); 195 return 0; 196 }
bzoj2761
bzoj十大水题之一?(虽然我知道的还有很多比这个还简单。。。)
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 #define maxn 50010 6 7 using namespace std; 8 9 int now[maxn]; 10 int a[maxn],b[maxn],c[maxn]; 11 12 int main() 13 { 14 int _; 15 scanf("%d",&_); 16 while (_--) 17 { 18 int n; 19 scanf("%d",&n); 20 for (int i=1;i<=n;i++) 21 { 22 scanf("%d",&a[i]); 23 b[i]=a[i]; 24 } 25 sort(b+1,b+n+1); 26 int size=unique(b+1,b+n+1)-b-1; 27 for (int i=1;i<=n;i++) 28 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 29 memset(now,0,sizeof(now)); 30 size=0; 31 for (int i=1;i<=n;i++) 32 if (!now[a[i]]) 33 { 34 now[a[i]]=1; 35 c[++size]=a[i]; 36 } 37 for (int i=1;i<size;i++) 38 printf("%d ",b[c[i]]); 39 printf("%d\n",b[c[size]]); 40 } 41 return 0; 42 }
bzoj2763
当时想了很久,然后一看K的范围,然后就写了个spfa。。。
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 5 using namespace std; 6 7 #define maxn 10010 8 #define maxm 50010 9 #define inf 0x3f3f3f3f 10 11 struct edge 12 { 13 int to,dist; 14 edge *next; 15 }e[maxm<<1],*head[maxn]; 16 17 int ne=0; 18 19 inline void add_edge(int from,int to,int dist) 20 { 21 e[ne].to=to; 22 e[ne].dist=dist; 23 e[ne].next=head[from]; 24 head[from]=&e[ne++]; 25 } 26 27 struct que 28 { 29 int x,y; 30 }; 31 32 int k; 33 int s,t; 34 int d[maxn][12]; 35 bool flag[maxn][12]; 36 37 deque <que> q; 38 39 inline void spfa() 40 { 41 memset(d,0x3f,sizeof(d)); 42 d[s][0]=0; 43 que now; 44 now.x=s; 45 now.y=0; 46 q.push_back(now); 47 while (!q.empty()) 48 { 49 int x=q.front().x,y=q.front().y; 50 q.pop_front(); 51 for (edge *p=head[x];p;p=p->next) 52 { 53 if (y < k && d[x][y] < d[p->to][y+1]) 54 { 55 d[p->to][y+1]=d[x][y]; 56 if (!flag[p->to][y+1]) 57 { 58 que now; 59 now.x=p->to; 60 now.y=y+1; 61 if (!q.empty()) 62 { 63 if (d[p->to][y+1] <= d[q.front().x][q.front().y]) 64 q.push_front(now); 65 else 66 q.push_back(now); 67 } 68 else 69 q.push_back(now); 70 flag[p->to][y+1]=1; 71 } 72 } 73 if (d[x][y]+p->dist < d[p->to][y]) 74 { 75 d[p->to][y]=d[x][y]+p->dist; 76 if (!flag[p->to][y]) 77 { 78 que now; 79 now.x=p->to; 80 now.y=y; 81 if (!q.empty()) 82 { 83 if (d[p->to][y] <= d[q.front().x][q.front().y]) 84 q.push_front(now); 85 else 86 q.push_back(now); 87 } 88 else 89 q.push_back(now); 90 flag[p->to][y]=1; 91 } 92 } 93 } 94 flag[x][y]=0; 95 } 96 } 97 98 int main() 99 { 100 // freopen("1.in","r",stdin); 101 // freopen("1.out","w",stdout); 102 int n,m; 103 scanf("%d%d%d",&n,&m,&k); 104 scanf("%d%d",&s,&t); 105 for (int i=1;i<=m;i++) 106 { 107 int x,y,z; 108 scanf("%d%d%d",&x,&y,&z); 109 add_edge(x,y,z); 110 add_edge(y,x,z); 111 } 112 spfa(); 113 int ans=inf; 114 for (int i=0;i<=k;i++) 115 ans=min(ans,d[t][i]); 116 printf("%d\n",ans); 117 return 0; 118 }
bzoj2764
水水的DP+很难的高精(粘模板的同学记得调整位数,小心T掉)
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #define maxn 2010 11 12 #ifdef unix 13 #define ll "%lld" 14 #else 15 #define ll "%I64d" 16 #endif 17 class wkint { 18 private: 19 long long a[40]; 20 int len; 21 public: 22 wkint(); 23 wkint(int t); 24 void read(); 25 void print(); 26 wkint operator + (const wkint &t) const; 27 wkint operator - (const wkint &t) const; 28 wkint operator * (const wkint &t) const; 29 wkint operator * (const int &t) const; 30 wkint operator ^ (const int &t) const; 31 wkint operator / (const int &t) const; 32 int operator % (const int &t) const; 33 bool operator < (const wkint &t) const; 34 bool operator > (const wkint &t) const; 35 bool operator == (const wkint &t) const; 36 bool operator != (const wkint &t) const; 37 }; 38 39 wkint::wkint() { 40 len = 1; 41 memset(a, 0, sizeof(a)); 42 } 43 wkint::wkint(int t) { 44 len = 1; 45 a[1] = t; 46 } 47 void wkint::read() { 48 string tmp; 49 cin >> tmp; 50 int lenT = tmp.length(); 51 len = (lenT + 7) / 8; 52 int ptr = len, now = 0; 53 for (int i = 0; i < lenT; i ++) { 54 now *= 10; now += (int)(tmp[i] - '0'); 55 if (!((lenT - i - 1) % 8)) { 56 a[ptr] = now; 57 now = 0; 58 ptr --; 59 } 60 } 61 } 62 void wkint::print() { 63 printf(ll, a[len]); 64 for (int i = len - 1; i >= 1; i --) { 65 int ws = (int)log10((long double)(a[i] + 1)) + 1; 66 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 67 printf(ll, a[i]); 68 } 69 printf("\n"); 70 } 71 wkint wkint::operator + (const wkint &t) const { 72 wkint res; 73 int maxlen = max(t.len, len); 74 for (int i = 1; i <= maxlen; i ++) { 75 res.a[i] += a[i] + t.a[i]; 76 if (res.a[i] >= 100000000) { 77 res.a[i + 1] += res.a[i] / 100000000; 78 res.a[i] %= 100000000; 79 } 80 } 81 if (res.a[maxlen + 1]) maxlen ++; 82 res.len = maxlen; 83 return res; 84 } 85 wkint wkint::operator - (const wkint &t) const { 86 wkint res; 87 int maxlen = max(t.len, len); 88 for (int i = 1; i <= maxlen; i ++) { 89 res.a[i] += a[i] - t.a[i]; 90 if (res.a[i] < 0) { 91 res.a[i + 1] -= 1; 92 res.a[i] += 100000000; 93 } 94 } 95 while (!res.a[maxlen]) maxlen --; 96 res.len = maxlen; 97 return res; 98 } 99 wkint wkint::operator * (const wkint &t) const { 100 wkint res; 101 int maxlen = t.len + len - 1; 102 for (int i = 1; i <= len; i ++) 103 for (int j = 1; j <= t.len; j ++) { 104 res.a[i + j - 1] += a[i] * t.a[j]; 105 } 106 for (int i = 1; i <= maxlen; i ++) 107 if (res.a[i] > 100000000) { 108 res.a[i + 1] += res.a[i] / 100000000; 109 res.a[i] %= 100000000; 110 } 111 if (res.a[maxlen + 1]) maxlen ++; 112 res.len = maxlen; 113 return res; 114 } 115 wkint wkint::operator * (const int &t) const { 116 wkint res; 117 res.len = len; 118 for (int i = 1; i <= len; i ++) { 119 res.a[i] += a[i] * t; 120 if (res.a[i] > 100000000) { 121 res.a[i + 1] += res.a[i] / 100000000; 122 res.a[i] %= 100000000; 123 } 124 } 125 if (res.a[res.len + 1]) res.len ++; 126 return res; 127 } 128 wkint wkint::operator ^ (const int &t) const { 129 wkint res = wkint(1), tmp; 130 int now = t; 131 memcpy(tmp.a, a, sizeof(a)); 132 tmp.len = len; 133 while (now) { 134 if (now & 1) res = res * tmp; 135 tmp = tmp * tmp; 136 now >>= 1; 137 } 138 return res; 139 } 140 wkint wkint::operator / (const int &t) const { 141 wkint res; 142 long long now = 0; 143 res.len = len; 144 for (int i = len; i >= 1; i --) { 145 now *= 100000000, now += a[i]; 146 if (now < t) { 147 res.a[i] = 0; 148 } else { 149 res.a[i] = now / t; 150 now %= t; 151 } 152 } 153 while (!res.a[res.len]) res.len --; 154 return res; 155 } 156 int wkint::operator % (const int &t) const { 157 long long now = 0; 158 for (int i = len; i >= 1; i --) { 159 now *= 100000000, now += a[i]; 160 now %= t; 161 } 162 return (int)now; 163 } 164 bool wkint::operator < (const wkint &t) const { 165 if (len < t.len) return true; 166 if (len > t.len) return false; 167 for (int i = len; i >= 1; i --) 168 if (a[i] < t.a[i]) { 169 return true; 170 } else if (a[i] > t.a[i]) { 171 return false; 172 } 173 return false; 174 } 175 bool wkint::operator > (const wkint &t) const { 176 if (len > t.len) return true; 177 if (len < t.len) return false; 178 for (int i = len; i >= 1; i --) 179 if (a[i] > t.a[i]) { 180 return true; 181 } else if (a[i] < t.a[i]) { 182 return false; 183 } 184 return false; 185 } 186 bool wkint::operator == (const wkint &t) const { 187 if (t.len != len) return false; 188 for (int i = 1; i <= len; i ++) 189 if (a[i] != t.a[i]) { 190 return false; 191 } 192 return true; 193 } 194 bool wkint::operator != (const wkint &t) const { 195 if (t.len != len) return true; 196 for (int i = 1; i <= len; i ++) 197 if (a[i] != t.a[i]) { 198 return true; 199 } 200 return false; 201 } 202 203 int a[maxn],b[maxn]; 204 char s[maxn]; 205 wkint f[maxn],g[maxn]; 206 207 int main() 208 { 209 int n,m; 210 scanf("%d%d",&n,&m); 211 scanf("%s",s+1); 212 for (int i=1;i<=n;i++) 213 { 214 if (s[i] == 'A') 215 a[i]=1; 216 if (s[i] == 'T') 217 a[i]=2; 218 if (s[i] == 'C') 219 a[i]=3; 220 if (s[i] == 'G') 221 a[i]=4; 222 } 223 scanf("%s",s+1); 224 for (int i=1;i<=m;i++) 225 { 226 if (s[i] == 'T') 227 b[i]=1; 228 if (s[i] == 'A') 229 b[i]=2; 230 if (s[i] == 'G') 231 b[i]=3; 232 if (s[i] == 'C') 233 b[i]=4; 234 } 235 f[0]=1; 236 g[0]=1; 237 wkint ans=0; 238 for (int i=1;i<=n;i++) 239 { 240 for (int j=m;j;j--) 241 { 242 if (a[i] == b[j]) 243 f[j]=g[j-1]; 244 else 245 f[j]=0; 246 g[j]=g[j]+f[j]; 247 } 248 ans=ans+f[m]; 249 } 250 ans.print(); 251 return 0; 252 }
bzoj2768
1934双倍经验
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 1010 5 #define maxm 1000010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int to,flow; 11 edge *next,*part; 12 }e[maxm],*head[maxn]; 13 14 int ne=0,s=0,t=maxn-1; 15 int d[maxn],q[maxn],a[maxn]; 16 17 inline int min(int a,int b) 18 { 19 return a < b ? a : b; 20 } 21 22 inline void add(int from,int to,int flow) 23 { 24 e[ne].to=to; 25 e[ne].flow=flow; 26 e[ne].next=head[from]; 27 head[from]=&e[ne++]; 28 } 29 30 inline void add_edge(int from,int to,int flow) 31 { 32 e[ne].part=&e[ne+1]; 33 e[ne+1].part=&e[ne]; 34 add(from,to,flow); 35 add(to,from,0); 36 } 37 38 inline void add_edge_other(int from,int to,int flow) 39 { 40 e[ne].part=&e[ne+1]; 41 e[ne+1].part=&e[ne]; 42 add(from,to,flow); 43 add(to,from,flow); 44 } 45 46 inline bool bfs() 47 { 48 memset(d,-1,sizeof(d)); 49 int op=0,cls=1; 50 q[1]=s; 51 d[s]=0; 52 while (op != cls) 53 { 54 int x=q[++op]; 55 for (edge *p=head[x];p;p=p->next) 56 if (p->flow && d[p->to] == -1) 57 { 58 d[p->to]=d[x]+1; 59 q[++cls]=p->to; 60 } 61 } 62 return d[t] != -1; 63 } 64 65 int dfs(int now,int now_flow) 66 { 67 if (now == t) 68 return now_flow; 69 int out=now_flow; 70 for (edge *p=head[now];p;p=p->next) 71 if (p->flow && d[p->to] == d[now]+1 && out) 72 { 73 int f=dfs(p->to,min(out,p->flow)); 74 p->flow-=f; 75 p->part->flow+=f; 76 out-=f; 77 } 78 if (now_flow == out) 79 d[now]=-1; 80 return now_flow-out; 81 } 82 83 inline int dinic() 84 { 85 int ans=0; 86 while (bfs()) 87 ans+=dfs(s,inf); 88 return ans; 89 } 90 91 int main() 92 { 93 int n,m; 94 scanf("%d%d",&n,&m); 95 for (int i=1;i<=n;i++) 96 scanf("%d",&a[i]); 97 for (int i=1;i<=m;i++) 98 { 99 int x,y; 100 scanf("%d%d",&x,&y); 101 if (a[x] == a[y]) 102 add_edge_other(x+a[x]*n,y+a[y]*n,1); 103 else 104 { 105 if (a[x] == 1) 106 x^=y^=x^=y; 107 add_edge(x,y+n,1); 108 } 109 } 110 for (int i=1;i<=n;i++) 111 { 112 add_edge(s,i,1); 113 add_edge(i+n,t,1); 114 } 115 printf("%d\n",dinic()); 116 return 0; 117 }
bzoj2783
树形DFS
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct edge 6 { 7 int to; 8 edge *next; 9 }e[maxn],*head[maxn]; 10 11 int ne=0,ans=0,s; 12 int a[maxn],val[maxn]; 13 14 inline void add_edge(int from,int to) 15 { 16 e[ne].to=to; 17 e[ne].next=head[from]; 18 head[from]=&e[ne++]; 19 } 20 21 void dfs(int now,int nowl,int nowr,int sum) 22 { 23 while (sum > s) 24 { 25 sum-=a[nowl]; 26 nowl++; 27 } 28 if (sum == s) 29 ans++; 30 for (edge *p=head[now];p;p=p->next) 31 { 32 a[nowr+1]=val[p->to]; 33 dfs(p->to,nowl,nowr+1,sum+val[p->to]); 34 } 35 } 36 37 int main() 38 { 39 int n; 40 scanf("%d%d",&n,&s); 41 for (int i=1;i<=n;i++) 42 scanf("%d",&val[i]); 43 for (int i=1;i<n;i++) 44 { 45 int x,y; 46 scanf("%d%d",&x,&y); 47 add_edge(x,y); 48 } 49 a[1]=val[1]; 50 dfs(1,1,1,a[1]); 51 printf("%d\n",ans); 52 return 0; 53 }
bzoj2809
这道题是我写过的唯一一道左偏树。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 #ifdef unix 9 #define LL "%lld" 10 #else 11 #define LL "%I64d" 12 #endif 13 14 struct edge 15 { 16 long long to; 17 edge *next; 18 }e[maxn<<1],*head[maxn]; 19 20 struct Node 21 { 22 long long v,d,size,sum; 23 Node *s[2]; 24 }tt[maxn],*t[maxn],null; 25 26 long long ne=0,cnt=0; 27 long long q[maxn],fa[maxn],l[maxn]; 28 29 Node* merge(Node* p,Node* q) 30 { 31 if (p == &null) 32 return q; 33 if (q == &null) 34 return p; 35 if (p->v < q->v) 36 swap(p,q); 37 p->s[1]=merge(p->s[1],q); 38 if (p->s[1]->d > p->s[0]->d) 39 swap(p->s[0],p->s[1]); 40 p->d=p->s[1]->d+1; 41 p->sum=p->s[0]->sum+p->s[1]->sum+p->v; 42 p->size=p->s[0]->size+p->s[1]->size+1; 43 return p; 44 } 45 46 inline Node* del(Node* now) 47 { 48 now=merge(now->s[0],now->s[1]); 49 return now; 50 } 51 52 inline void add_edge(long long from,long long to) 53 { 54 e[ne].to=to; 55 e[ne].next=head[from]; 56 head[from]=&e[ne++]; 57 } 58 59 inline void bfs() 60 { 61 long long op=0,cls=1; 62 q[1]=1; 63 while (op != cls) 64 { 65 long long x=q[++op]; 66 for (edge *p=head[x];p;p=p->next) 67 if (p->to != fa[x]) 68 q[++cls]=p->to; 69 } 70 } 71 72 int main() 73 { 74 null.s[0]=null.s[1]=&null; 75 null.v=null.size=null.sum=0; 76 long long n,m; 77 scanf(LL LL,&n,&m); 78 for (long long i=1;i<=n;i++) 79 { 80 long long x; 81 scanf(LL LL LL,&fa[i],&x,&l[i]); 82 if (fa[i]) 83 { 84 add_edge(i,fa[i]); 85 add_edge(fa[i],i); 86 } 87 Node* now=&tt[cnt++]; 88 now->s[0]=now->s[1]=&null; 89 now->v=now->sum=x; 90 now->size=1; 91 now->d=0; 92 t[i]=now; 93 } 94 bfs(); 95 long long ans=0; 96 for (long long i=n;i;i--) 97 { 98 long long x=q[i]; 99 for (edge *p=head[x];p;p=p->next) 100 if (p->to != fa[x]) 101 t[x]=merge(t[x],t[p->to]); 102 while (t[x]->sum > m) 103 t[x]=del(t[x]); 104 ans=max(ans,l[x]*t[x]->size); 105 } 106 printf(LL,ans); 107 return 0; 108 }
bzoj2822
卡特兰数+高精
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #ifdef unix 11 #define ll "%lld" 12 #else 13 #define ll "%I64d" 14 #endif 15 class wkint { 16 private: 17 long long a[1510]; 18 int len; 19 public: 20 wkint(); 21 wkint(int t); 22 void read(); 23 void print(); 24 wkint operator + (const wkint &t) const; 25 wkint operator - (const wkint &t) const; 26 wkint operator * (const wkint &t) const; 27 wkint operator * (const int &t) const; 28 wkint operator ^ (const int &t) const; 29 wkint operator / (const int &t) const; 30 int operator % (const int &t) const; 31 bool operator < (const wkint &t) const; 32 bool operator > (const wkint &t) const; 33 bool operator == (const wkint &t) const; 34 bool operator != (const wkint &t) const; 35 }; 36 37 wkint::wkint() { 38 len = 1; 39 memset(a, 0, sizeof(a)); 40 } 41 wkint::wkint(int t) { 42 len = 1; 43 a[1] = t; 44 } 45 void wkint::read() { 46 string tmp; 47 cin >> tmp; 48 int lenT = tmp.length(); 49 len = (lenT + 7) / 8; 50 int ptr = len, now = 0; 51 for (int i = 0; i < lenT; i ++) { 52 now *= 10; now += (int)(tmp[i] - '0'); 53 if (!((lenT - i - 1) % 8)) { 54 a[ptr] = now; 55 now = 0; 56 ptr --; 57 } 58 } 59 } 60 void wkint::print() { 61 printf(ll, a[len]); 62 for (int i = len - 1; i >= 1; i --) { 63 int ws = (int)log10((long double)(a[i] + 1)) + 1; 64 for (int j = 1; j <= 8 - ws; j ++) printf("0"); 65 printf(ll, a[i]); 66 } 67 printf("\n"); 68 } 69 wkint wkint::operator + (const wkint &t) const { 70 wkint res; 71 int maxlen = max(t.len, len); 72 for (int i = 1; i <= maxlen; i ++) { 73 res.a[i] += a[i] + t.a[i]; 74 if (res.a[i] >= 100000000) { 75 res.a[i + 1] += res.a[i] / 100000000; 76 res.a[i] %= 100000000; 77 } 78 } 79 if (res.a[maxlen + 1]) maxlen ++; 80 res.len = maxlen; 81 return res; 82 } 83 wkint wkint::operator - (const wkint &t) const { 84 wkint res; 85 int maxlen = max(t.len, len); 86 for (int i = 1; i <= maxlen; i ++) { 87 res.a[i] += a[i] - t.a[i]; 88 if (res.a[i] < 0) { 89 res.a[i + 1] -= 1; 90 res.a[i] += 100000000; 91 } 92 } 93 while (!res.a[maxlen]) maxlen --; 94 res.len = maxlen; 95 return res; 96 } 97 wkint wkint::operator * (const wkint &t) const { 98 wkint res; 99 int maxlen = t.len + len - 1; 100 for (int i = 1; i <= len; i ++) 101 for (int j = 1; j <= t.len; j ++) { 102 res.a[i + j - 1] += a[i] * t.a[j]; 103 } 104 for (int i = 1; i <= maxlen; i ++) 105 if (res.a[i] > 100000000) { 106 res.a[i + 1] += res.a[i] / 100000000; 107 res.a[i] %= 100000000; 108 } 109 if (res.a[maxlen + 1]) maxlen ++; 110 res.len = maxlen; 111 return res; 112 } 113 wkint wkint::operator * (const int &t) const { 114 wkint res; 115 res.len = len; 116 for (int i = 1; i <= len; i ++) { 117 res.a[i] += a[i] * t; 118 if (res.a[i] > 100000000) { 119 res.a[i + 1] += res.a[i] / 100000000; 120 res.a[i] %= 100000000; 121 } 122 } 123 if (res.a[res.len + 1]) res.len ++; 124 return res; 125 } 126 wkint wkint::operator ^ (const int &t) const { 127 wkint res = wkint(1), tmp; 128 int now = t; 129 memcpy(tmp.a, a, sizeof(a)); 130 tmp.len = len; 131 while (now) { 132 if (now & 1) res = res * tmp; 133 tmp = tmp * tmp; 134 now >>= 1; 135 } 136 return res; 137 } 138 wkint wkint::operator / (const int &t) const { 139 wkint res; 140 long long now = 0; 141 res.len = len; 142 for (int i = len; i >= 1; i --) { 143 now *= 100000000, now += a[i]; 144 if (now < t) { 145 res.a[i] = 0; 146 } else { 147 res.a[i] = now / t; 148 now %= t; 149 } 150 } 151 while (!res.a[res.len]) res.len --; 152 return res; 153 } 154 int wkint::operator % (const int &t) const { 155 long long now = 0; 156 for (int i = len; i >= 1; i --) { 157 now *= 100000000, now += a[i]; 158 now %= t; 159 } 160 return (int)now; 161 } 162 bool wkint::operator < (const wkint &t) const { 163 if (len < t.len) return true; 164 if (len > t.len) return false; 165 for (int i = len; i >= 1; i --) 166 if (a[i] < t.a[i]) { 167 return true; 168 } else if (a[i] > t.a[i]) { 169 return false; 170 } 171 return false; 172 } 173 bool wkint::operator > (const wkint &t) const { 174 if (len > t.len) return true; 175 if (len < t.len) return false; 176 for (int i = len; i >= 1; i --) 177 if (a[i] > t.a[i]) { 178 return true; 179 } else if (a[i] < t.a[i]) { 180 return false; 181 } 182 return false; 183 } 184 bool wkint::operator == (const wkint &t) const { 185 if (t.len != len) return false; 186 for (int i = 1; i <= len; i ++) 187 if (a[i] != t.a[i]) { 188 return false; 189 } 190 return true; 191 } 192 bool wkint::operator != (const wkint &t) const { 193 if (t.len != len) return true; 194 for (int i = 1; i <= len; i ++) 195 if (a[i] != t.a[i]) { 196 return true; 197 } 198 return false; 199 } 200 201 wkint ans=1; 202 203 int main() 204 { 205 int n; 206 scanf("%d",&n); 207 for (int i=n+1;i<=2*n;i++) 208 ans=ans*i; 209 for (int i=2;i<=n;i++) 210 ans=ans/i; 211 ans=ans/(n+1); 212 ans.print(); 213 return 0; 214 }
bzoj2823
最小圆覆盖
1 #include <cstdio> 2 #include <cmath> 3 4 #define maxn 500010 5 #define eps 1e-8 6 7 struct Node 8 { 9 double x,y; 10 }a[maxn],now; 11 12 inline double dist(Node a,Node b) 13 { 14 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 15 } 16 17 inline void set_circle(int x,int y,int z) 18 { 19 double d1=a[x].x*a[x].x+a[x].y*a[x].y; 20 double d2=a[y].x*a[y].x+a[y].y*a[y].y; 21 double d3=a[z].x*a[z].x+a[z].y*a[z].y; 22 double dx1=a[x].x-a[y].x,dx2=a[y].x-a[z].x; 23 double dy1=a[x].y-a[y].y,dy2=a[y].y-a[z].y; 24 now.x=((d2-d3)*dy1-(d1-d2)*dy2)/(dx2*dy1-dx1*dy2)/2; 25 now.y=(d1-d2-2*now.x*dx1)/dy1/2; 26 } 27 28 int main() 29 { 30 int n; 31 scanf("%d",&n); 32 for (int i=1;i<=n;i++) 33 scanf("%lf%lf",&a[i].x,&a[i].y); 34 now=a[1]; 35 double nowr=0; 36 for (int i=2;i<=n;i++) 37 if (dist(a[i],now) > nowr && fabs(dist(a[i],now)-nowr) > eps) 38 { 39 now=a[i]; 40 nowr=0; 41 for (int j=1;j<i;j++) 42 if (dist(a[j],now) > nowr && fabs(dist(a[j],now)-nowr) > eps) 43 { 44 now.x=(a[i].x+a[j].x)/2; 45 now.y=(a[i].y+a[j].y)/2; 46 nowr=dist(a[i],a[j])/2; 47 for (int k=1;k<j;k++) 48 if (dist(a[k],now) > nowr && fabs(dist(a[k],now)-nowr) > eps) 49 { 50 set_circle(i,j,k); 51 nowr=dist(a[i],now); 52 } 53 } 54 } 55 printf("%.2lf %.2lf %.2lf\n",now.x,now.y,nowr); 56 return 0; 57 }
bzoj2875
矩阵快速幂,注意不能直接乘,要用快速加法
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 10 5 6 long long mod,a,c,x0,n,g; 7 long long temp[maxn][maxn],ans[maxn][maxn],wk[maxn][maxn]; 8 9 inline long long quickadd(long long a,long long b) 10 { 11 long long ans=0,wk=a; 12 for (;b;b>>=1) 13 { 14 if (b&1) 15 (ans+=wk)%=mod; 16 (wk+=wk)%=mod; 17 } 18 return ans; 19 } 20 21 int main() 22 { 23 scanf("%lld%lld%lld%lld%lld%lld",&mod,&a,&c,&x0,&n,&g); 24 x0%=mod; 25 c%=mod; 26 ans[1][1]=x0; 27 ans[1][2]=c; 28 wk[1][1]=a; 29 wk[2][1]=1; 30 wk[2][2]=1; 31 for (;n;n>>=1) 32 { 33 if (n&1) 34 { 35 memset(temp,0,sizeof(temp)); 36 for (long long i=1;i<=2;i++) 37 for (long long j=1;j<=2;j++) 38 for (long long k=1;k<=2;k++) 39 (temp[i][j]+=quickadd(ans[i][k],wk[k][j]))%=mod; 40 for (long long i=1;i<=2;i++) 41 for (long long j=1;j<=2;j++) 42 ans[i][j]=temp[i][j]; 43 } 44 memset(temp,0,sizeof(temp)); 45 for (long long i=1;i<=2;i++) 46 for (long long j=1;j<=2;j++) 47 for (long long k=1;k<=2;k++) 48 (temp[i][j]+=quickadd(wk[i][k],wk[k][j]))%=mod; 49 for (long long i=1;i<=2;i++) 50 for (long long j=1;j<=2;j++) 51 wk[i][j]=temp[i][j]; 52 } 53 printf("%lld\n",ans[1][1]%g); 54 return 0; 55 }
bzoj2957
等价于求某个数列中有多少个数比它前面的都大,线段树,然后一个奇奇怪怪的维护。。。
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 int ans; 8 double val; 9 }t[maxn<<2]; 10 11 #define max(a,b) ((a) > (b) ? (a) : (b)) 12 13 inline int calc(int l,int r,int rt,double val) 14 { 15 if (l == r) 16 return t[rt].val > val; 17 int mid=(l+r)>>1; 18 if (t[rt<<1].val <= val) 19 return calc(mid+1,r,rt<<1|1,val); 20 return t[rt].ans-t[rt<<1].ans+calc(l,mid,rt<<1,val); 21 } 22 23 inline void insert(int l,int r,int rt,int pos,double val) 24 { 25 if (l == r) 26 { 27 t[rt].val=val; 28 t[rt].ans=1; 29 return; 30 } 31 int mid=(l+r)>>1; 32 if (pos <= mid) 33 insert(l,mid,rt<<1,pos,val); 34 else 35 insert(mid+1,r,rt<<1|1,pos,val); 36 t[rt].val=max(t[rt<<1].val,t[rt<<1|1].val); 37 t[rt].ans=t[rt<<1].ans+calc(mid+1,r,rt<<1|1,t[rt<<1].val); 38 } 39 40 inline void read(int &x) 41 { 42 x=0; 43 char ch; 44 while (ch=getchar(),ch > '9' || ch < '0'); 45 x=ch-'0'; 46 while (ch=getchar(),ch <= '9' && ch >= '0') 47 x=(x<<3)+x+x+ch-'0'; 48 } 49 50 int main() 51 { 52 int n,m; 53 scanf("%d%d",&n,&m); 54 while (m--) 55 { 56 int x,y; 57 scanf("%d%d",&x,&y); 58 insert(1,n,1,x,(double)y/x); 59 printf("%d\n",t[1].ans); 60 } 61 return 0; 62 }
bzoj2962
奇葩的询问。。。还好只有20。。。每次20^2维护答案即可,建议手推一下
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 50010 5 #define mod 19940417LL 6 7 inline long long min(long long a,long long b) 8 { 9 return a < b ? a : b; 10 } 11 12 inline long long max(long long a,long long b) 13 { 14 return a > b ? a : b; 15 } 16 17 long long c[maxn][21]; 18 19 struct Node 20 { 21 long long add,size; 22 bool lazy; 23 long long ans[21]; 24 25 inline Node() 26 { 27 memset(ans,0,sizeof(ans)); 28 ans[0]=1; 29 } 30 31 inline Node operator + (const Node a) 32 { 33 Node now; 34 now.size=size+a.size; 35 for (long long i=1;i<=min(20LL,now.size);i++) 36 for (long long j=0;j<=min(i,size);j++) 37 if (i-j <= a.size) 38 (now.ans[i]+=ans[j]*a.ans[i-j])%=mod; 39 return now; 40 } 41 }t[maxn<<2]; 42 43 inline void _update(long long rt) 44 { 45 for (long long i=1;i<=min(t[rt].size,20LL);i++) 46 { 47 t[rt].ans[i]=0; 48 for (long long j=0;j<=min(t[rt<<1].size,20LL) && j<=i;j++) 49 if (i-j <= t[rt<<1|1].size) 50 (t[rt].ans[i]+=t[rt<<1].ans[j]*t[rt<<1|1].ans[i-j])%=mod; 51 } 52 } 53 54 inline void change(long long rt,long long d) 55 { 56 for (long long i=min(t[rt].size,20LL);i;i--) 57 { 58 long long now=d; 59 for (long long j=1;j<=i;j++) 60 { 61 (t[rt].ans[i]+=t[rt].ans[i-j]*c[t[rt].size-i+j][j]%mod*now)%=mod; 62 (now*=d)%=mod; 63 } 64 } 65 } 66 67 inline void _pushdown(long long rt) 68 { 69 if (t[rt].lazy) 70 { 71 t[rt].lazy^=1; 72 t[rt<<1].lazy^=1; 73 t[rt<<1|1].lazy^=1; 74 t[rt<<1].add*=-1; 75 t[rt<<1].add+=mod; 76 t[rt<<1|1].add*=-1; 77 t[rt<<1|1].add+=mod; 78 for (long long i=1;i<20;i+=2) 79 { 80 t[rt<<1].ans[i]*=-1; 81 t[rt<<1].ans[i]+=mod; 82 t[rt<<1|1].ans[i]*=-1; 83 t[rt<<1|1].ans[i]+=mod; 84 } 85 } 86 if (t[rt].add) 87 { 88 long long d=t[rt].add; 89 (t[rt<<1].add+=d)%=mod; 90 (t[rt<<1|1].add+=d)%=mod; 91 t[rt].add=0; 92 change(rt<<1,d); 93 change(rt<<1|1,d); 94 } 95 } 96 97 void build(long long l,long long r,long long rt) 98 { 99 t[rt].size=r-l+1; 100 if (l == r) 101 { 102 scanf("%lld",&t[rt].ans[1]); 103 t[rt].ans[1]%=mod; 104 return; 105 } 106 long long mid=(l+r)>>1; 107 build(l,mid,rt<<1); 108 build(mid+1,r,rt<<1|1); 109 _update(rt); 110 } 111 112 void insert(long long l,long long r,long long rt,long long L,long long R,long long add) 113 { 114 if (l >= L && r <= R) 115 { 116 (t[rt].add+=add)%=mod; 117 change(rt,add); 118 return; 119 } 120 long long mid=(l+r)>>1; 121 _pushdown(rt); 122 if (L <= mid) 123 insert(l,mid,rt<<1,L,R,add); 124 if (R > mid) 125 insert(mid+1,r,rt<<1|1,L,R,add); 126 _update(rt); 127 } 128 129 void change(long long l,long long r,long long rt,long long L,long long R) 130 { 131 if (l >= L && r <= R) 132 { 133 for (long long i=1;i<20;i+=2) 134 { 135 t[rt].ans[i]*=-1; 136 t[rt].ans[i]+=mod; 137 } 138 t[rt].lazy^=1; 139 t[rt].add*=-1; 140 t[rt].add+=mod; 141 return; 142 } 143 long long mid=(l+r)>>1; 144 _pushdown(rt); 145 if (L <= mid) 146 change(l,mid,rt<<1,L,R); 147 if (R > mid) 148 change(mid+1,r,rt<<1|1,L,R); 149 _update(rt); 150 } 151 152 Node query(long long l,long long r,long long rt,long long L,long long R) 153 { 154 if (l >= L && r <= R) 155 return t[rt]; 156 _pushdown(rt); 157 long long mid=(l+r)>>1; 158 if (R <= mid) 159 return query(l,mid,rt<<1,L,R); 160 else 161 { 162 if (L > mid) 163 return query(mid+1,r,rt<<1|1,L,R); 164 else 165 return query(l,mid,rt<<1,L,R)+query(mid+1,r,rt<<1|1,L,R); 166 } 167 } 168 169 int main() 170 { 171 long long n,q; 172 scanf("%lld%lld",&n,&q); 173 build(1,n,1); 174 c[0][0]=1; 175 for (long long i=1;i<=n;i++) 176 { 177 c[i][0]=1; 178 if (i <= 20) 179 c[i][i]=1; 180 for (long long j=1;j<=min(20LL,i-1);j++) 181 c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; 182 } 183 while (q--) 184 { 185 char s[2]; 186 long long x,y,z; 187 scanf("%s%lld%lld",s,&x,&y); 188 if (s[0] == 'I') 189 { 190 scanf("%lld",&z); 191 z%=mod; 192 insert(1,n,1,x,y,z); 193 } 194 if (s[0] == 'R') 195 change(1,n,1,x,y); 196 if (s[0] == 'Q') 197 { 198 scanf("%lld",&z); 199 long long ans=query(1,n,1,x,y).ans[z]; 200 if (ans < 0) 201 ans+=mod; 202 ans%=mod; 203 printf("%lld\n",ans); 204 } 205 } 206 return 0; 207 }
bzoj3040
我能说spfa+slf+读入优化跑得飞快?
1 #include<cstdlib> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 deque<int>q; 9 bool instack[1000010]; 10 long long dis[1000010]; 11 struct Edge 12 { 13 long long v; 14 int p,ne; 15 }e[10000100]; 16 int er,head[1000010]; 17 18 int p,T,n,m; 19 int a,b,v; 20 long long x,y,z,rxa,rxc,rya,ryc,rp; 21 22 inline void add_edge(int a,int b,long long v) 23 { 24 e[++er].p = b; 25 e[er].v = v; 26 e[er].ne = head[a]; 27 head[a] = er; 28 } 29 30 void spfa() 31 { 32 memset(dis,0x3f3f,sizeof(dis)); 33 dis[1] = 0; 34 instack[1] = 1; 35 for (q.push_back(1);!q.empty();q.pop_front()) 36 { 37 p = q.front(); 38 for (int z=head[p];z;z=e[z].ne) 39 if (dis[e[z].p] >(dis[p] + e[z].v)) 40 { 41 dis[e[z].p] = dis[p] + e[z].v; 42 if (!instack[e[z].p]) 43 { 44 if (!q.empty()) 45 { 46 if (dis[e[z].p] <= dis[q.front()]) 47 q.push_front(e[z].p); 48 else 49 q.push_back(e[z].p); 50 } 51 else 52 q.push_back(e[z].p); 53 instack[e[z].p] = 1; 54 } 55 } 56 instack[p] = 0; 57 } 58 } 59 60 char c; 61 inline void read(int &x) 62 { 63 while (c=getchar(),c<'0'||c>'9'); 64 x = c - '0'; 65 while (c=getchar(),c>='0'&&c<='9') 66 x = (x<<3)+(x<<1)+c-'0'; 67 } 68 69 int main() 70 { 71 read(n); 72 read(m); 73 read(T); 74 scanf("%lld%lld%lld%lld%lld",&rxa,&rxc,&rya,&ryc,&rp); 75 x=y=z=0; 76 for (int i = 1;i <= T;++ i) 77 { 78 long long x=(x*rxa+rxc)%rp; 79 long long y=(y*rya+ryc)%rp; 80 long long a=min(x%n+1,y%n+1); 81 long long b=max(y%n+1,y%n+1); 82 add_edge(a,b,1e8-100*a); 83 } 84 for (int i = 1;i <= m-T;++i) 85 { 86 read(a); 87 read(b); 88 read(v); 89 add_edge(a,b,v); 90 } 91 spfa(); 92 printf("%lld",dis[n]); 93 return 0; 94 }
bzoj3098
考验自己生日的时候到了,或者用妹子(有妹子的可以试试)的生日试一下?
1 #include <cstdio> 2 #include <cstdlib> 3 4 int main() 5 { 6 printf("100000 10\n"); 7 srand(19960226); 8 for (int i=1;i<=100000;i++) 9 printf("%c",rand()%26+'a'); 10 return 0; 11 }
bzoj3110
值域线段树套朴素线段树
1 #include <cstdio> 2 3 #define maxn 50010 4 5 struct Node 6 { 7 long long sum,add; 8 Node* s[2]; 9 }t[maxn*300],*root[maxn<<2],null; 10 11 int n,ne=0; 12 13 inline Node* new_Node() 14 { 15 Node* now=&t[ne++]; 16 now->sum=now->add=0; 17 now->s[0]=now->s[1]=&null; 18 return now; 19 } 20 21 inline void _pushdown(int l,int r,Node* now) 22 { 23 if (now->add) 24 { 25 if (now->s[0] == &null) 26 now->s[0]=new_Node(); 27 if (now->s[1] == &null) 28 now->s[1]=new_Node(); 29 long long add=now->add; 30 int mid=(l+r)>>1; 31 now->s[0]->add+=add; 32 now->s[0]->sum+=add*(mid-l+1); 33 now->s[1]->add+=add; 34 now->s[1]->sum+=add*(r-mid); 35 now->add=0; 36 } 37 } 38 39 inline void _update(Node* now) 40 { 41 now->sum=now->s[0]->sum+now->s[1]->sum; 42 } 43 44 void insert_seg(int l,int r,Node* now,int L,int R,int add) 45 { 46 if (l >= L && r <= R) 47 { 48 now->add+=add; 49 now->sum+=add*(r-l+1); 50 return; 51 } 52 _pushdown(l,r,now); 53 int mid=(l+r)>>1; 54 if (L <= mid) 55 { 56 if (now->s[0] == &null) 57 now->s[0]=new_Node(); 58 insert_seg(l,mid,now->s[0],L,R,add); 59 } 60 if (R > mid) 61 { 62 if (now->s[1] == &null) 63 now->s[1]=new_Node(); 64 insert_seg(mid+1,r,now->s[1],L,R,add); 65 } 66 _update(now); 67 } 68 69 inline void insert(int l,int r,int rt,int L,int R,int val) 70 { 71 while (1) 72 { 73 insert_seg(1,n,root[rt],L,R,1); 74 if (l == r) 75 return; 76 int mid=(l+r)>>1; 77 if (val <= mid) 78 { 79 r=mid; 80 rt<<=1; 81 } 82 else 83 { 84 l=mid+1; 85 (rt<<=1)|=1; 86 } 87 } 88 } 89 90 inline long long query_seg(int l,int r,Node* now,int L,int R) 91 { 92 if (l >= L && r <= R) 93 return now->sum; 94 _pushdown(l,r,now); 95 int mid=(l+r)>>1; 96 long long ans=0; 97 if (L <= mid) 98 if (now->s[0] != &null) 99 ans+=query_seg(l,mid,now->s[0],L,R); 100 if (R > mid) 101 if (now->s[1] != &null) 102 ans+=query_seg(mid+1,r,now->s[1],L,R); 103 return ans; 104 } 105 106 inline int query(int l,int r,int rt,int L,int R,long long k) 107 { 108 while (1) 109 { 110 if (l == r) 111 return l; 112 long long del=query_seg(1,n,root[rt<<1|1],L,R); 113 int mid=(l+r)>>1; 114 if (k <= del) 115 { 116 l=mid+1; 117 (rt<<=1)|=1; 118 } 119 else 120 { 121 k-=del; 122 r=mid; 123 rt<<=1; 124 } 125 } 126 } 127 128 int main() 129 { 130 null.s[0]=null.s[1]=&null; 131 null.sum=null.add=0; 132 int _; 133 scanf("%d%d",&n,&_); 134 for (int i=1;i<=(n<<2);i++) 135 root[i]=new_Node(); 136 while (_--) 137 { 138 int x,y,z,w; 139 scanf("%d%d%d%d",&x,&y,&z,&w); 140 if (x == 1) 141 insert(1,n,1,y,z,w); 142 else 143 printf("%d\n",query(1,n,1,y,z,w)); 144 } 145 return 0; 146 }
bzoj3111
水水的DP,有一个前缀和(?)优化
1 #include <cstdio> 2 3 #define maxn 110 4 #define maxk 22 5 #define inf 0x3f3f3f3f 6 7 int n,m,K; 8 int f[maxn][maxn][maxk],a[maxn][maxn],sum[maxn][maxn],up_max[maxn][maxn],down_max[maxn][maxn]; 9 10 inline int max(int a,int b) 11 { 12 return a > b ? a : b; 13 } 14 15 int main() 16 { 17 // freopen("ant.in","r",stdin); 18 // freopen("ant.out","w",stdout); 19 scanf("%d%d%d",&n,&m,&K); 20 (K<<=1)|=1; 21 for (int i=n;i;i--) 22 for (int j=1;j<=m;j++) 23 scanf("%d",&a[j][i]); 24 for (int i=1;i<=m;i++) 25 for (int j=1;j<=n;j++) 26 sum[i][j]=sum[i][j-1]+a[i][j]; 27 int ans=-inf; 28 for (int minl=0;minl<=n-2+(K == 1);minl++) 29 { 30 for (int i=0;i<=m;i++) 31 for (int j=0;j<=n;j++) 32 for (int k=0;k<=K;k++) 33 f[i][j][k]=-inf; 34 for (int i=1;i<=m;i++) 35 for (int j=minl+1;j<=n;j++) 36 f[i][j][1]=sum[i][j]-sum[i][minl]; 37 for (int i=0;i<=m+1;i++) 38 for (int j=0;j<=n+1;j++) 39 up_max[i][j]=down_max[i][j]=-inf; 40 for (int k=1;k<=K;k++) 41 { 42 for (int i=1;i<=m;i++) 43 for (int j=minl+1;j<=n;j++) 44 { 45 f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+sum[i][j]-sum[i][minl]); 46 if (k & 1) 47 f[i][j][k]=max(f[i][j][k],up_max[i-1][j-1]+sum[i][j]-sum[i][minl]); 48 else 49 f[i][j][k]=max(f[i][j][k],down_max[i-1][j+1]+sum[i][j]-sum[i][minl]); 50 } 51 for (int i=1;i<=m;i++) 52 { 53 for (int j=1;j<=n;j++) 54 up_max[i][j]=max(up_max[i][j-1],f[i][j][k]); 55 for (int j=n;j;j--) 56 down_max[i][j]=max(down_max[i][j+1],f[i][j][k]); 57 } 58 } 59 for (int i=1;i<=m;i++) 60 for (int j=1;j<=n;j++) 61 ans=max(ans,f[i][j][K]); 62 } 63 printf("%d\n",ans); 64 return 0; 65 }
bzoj3112
线性规划,据说需要各种对偶还要zkw费用流,写单纯形的表示压力有点大。。。
1 #include <cstdio> 2 3 #define maxn 1010 4 #define maxm 10010 5 #define inf 0x3f3f3f3f 6 7 int n,m; 8 int a[maxn][maxm]; 9 int next[maxm]; 10 11 inline void pivot(int l,int e) 12 { 13 int t=0; 14 for (int i=0;i<=m;i++) 15 if (a[l][i]) 16 { 17 next[t]=i; 18 t=i; 19 } 20 next[t]=-1; 21 for (int i=0;i<=n;i++) 22 { 23 if ((!a[i][e]) || i == l) 24 continue; 25 for (int j=0;j!=-1;j=next[j]) 26 { 27 if (j == e) 28 continue; 29 a[i][j]-=a[l][j]*a[i][e]; 30 } 31 a[i][e]=-a[i][e]; 32 } 33 } 34 35 inline int simplex() 36 { 37 for (;;) 38 { 39 int e=0; 40 for (int i=1;i<=m;i++) 41 if (a[0][i] > 0) 42 { 43 e=i; 44 break; 45 } 46 if (!e) 47 return -a[0][0]; 48 int pos,ans=inf; 49 for (int i=1;i<=n;i++) 50 if (a[i][e] > 0 && a[i][0] < ans) 51 { 52 ans=a[i][0]; 53 pos=i; 54 } 55 pivot(pos,e); 56 } 57 } 58 59 inline void read(int &x) 60 { 61 char ch; 62 while (ch=getchar(),ch > '9' || ch < '0'); 63 x=ch-'0'; 64 while (ch=getchar(),ch <= '9' && ch >= '0') 65 x=(x<<3)+x+x+ch-'0'; 66 } 67 68 int main() 69 { 70 read(n); 71 read(m); 72 for (int i=1;i<=n;i++) 73 read(a[i][0]); 74 for (int i=1;i<=m;i++) 75 { 76 int x=0,y=0; 77 read(x); 78 read(y); 79 read(a[0][i]); 80 for (int j=x;j<=y;j++) 81 a[j][i]=1; 82 } 83 printf("%d\n",simplex()); 84 return 0; 85 }
bzoj3118
线性规划,至今不会怎么转成费用流模型。。。
1 #include <cstdio> 2 #include <cstring> 3 4 #define maxn 1010 5 #define maxm 3010 6 #define inf 0x3f3f3f3f 7 8 struct edge 9 { 10 int from,to,num; 11 edge *next; 12 }e[maxm],*head[maxn],*prev[maxn]; 13 14 int ne=0,cnt=0; 15 int n,m; 16 int q[maxn]; 17 int from[maxm],to[maxm],w[maxm],inc[maxm],dec[maxm],flag[maxm]; 18 int a[maxn][20010]; 19 int next[maxn]; 20 bool vis[maxn]; 21 22 inline void add_edge(int from,int to,int num) 23 { 24 e[ne].to=to; 25 e[ne].from=from; 26 e[ne].num=num; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void find(int s,int t,int n) 32 { 33 int op=0,cls=1; 34 q[1]=s; 35 memset(vis,0,sizeof(vis)); 36 vis[s]=1; 37 prev[s]=0; 38 while (op != cls) 39 { 40 int x=q[++op]; 41 for (edge *p=head[x];p;p=p->next) 42 if (!vis[p->to]) 43 { 44 vis[p->to]=1; 45 prev[p->to]=p; 46 q[++cls]=p->to; 47 if (p->to == t) 48 break; 49 } 50 } 51 for (edge *p=prev[t];p;p=prev[p->from]) 52 { 53 int now=p->num; 54 cnt++; 55 a[now][cnt]=a[n][cnt]=1; 56 a[0][cnt]=w[now]-w[n]; 57 } 58 } 59 60 inline void pivot(int l,int e) 61 { 62 int t=0; 63 for(int i=0;i<=cnt;i++) 64 if(a[l][i]) 65 next[t]=i,t=i; 66 next[t]=-1; 67 for(int i=0;i<=m;i++) 68 { 69 if(a[i][e] == 0 || i == l) 70 continue; 71 for(int j=0;j!=-1;j=next[j]) 72 { 73 if(j == e) 74 continue; 75 a[i][j]-=a[l][j]*a[i][e]; 76 } 77 a[i][e]=-a[i][e]; 78 } 79 } 80 81 inline int simplex() 82 { 83 for(;;) 84 { 85 int e=0; 86 for(int i=1;i<=cnt;i++) 87 if(a[0][i] > 0) 88 { 89 e=i; 90 break; 91 } 92 if(!e) 93 return -a[0][0]; 94 int pos,ans=inf; 95 for(int i=1;i<=m;i++) 96 if(a[i][e] > 0 && a[i][0] < ans) 97 ans=a[i][0],pos = i; 98 pivot(pos,e); 99 } 100 } 101 102 inline void read(int &x) 103 { 104 char ch; 105 while (ch=getchar(),ch > '9' || ch < '0'); 106 x=ch-'0'; 107 while (ch=getchar(),ch <= '9' && ch >= '0') 108 x=(x<<3)+x+x+ch-'0'; 109 } 110 111 int main() 112 { 113 read(n); 114 read(m); 115 for (int i=1;i<=m;i++) 116 { 117 read(from[i]); 118 read(to[i]); 119 read(w[i]); 120 read(flag[i]); 121 read(inc[i]); 122 read(dec[i]); 123 if (flag[i]) 124 { 125 add_edge(from[i],to[i],i); 126 add_edge(to[i],from[i],i); 127 } 128 } 129 for (int i=1;i<=m;i++) 130 if (!flag[i]) 131 find(from[i],to[i],i); 132 for (int i=1;i<=m;i++) 133 a[i][0]=flag[i] ? dec[i] : inc[i]; 134 printf("%d\n",simplex()); 135 return 0; 136 }
bzoj3119(居然已隐藏?)
orz wd神犇。。。手推一下就知道怎么做了
1 #include <cstdio> 2 3 #ifdef unix 4 #define LL "%lld" 5 #else 6 #define LL "%I64d" 7 #endif 8 9 long long n,x,a,b,m,t; 10 11 int main() 12 { 13 scanf(LL,&n); 14 scanf(LL LL LL LL,&x,&a,&b,&m); 15 t=(n*(n-1)/2*b+m-n*x)/(a+b); 16 long long now=x; 17 long long i; 18 printf(LL " ",x); 19 for (i=2;t >= n-i+1 && i <= n;i++) 20 { 21 now+=a; 22 printf(LL " ",now); 23 t-=n-i+1; 24 } 25 for (;i<=n;i++) 26 { 27 if (n-i+1 == t) 28 { 29 now+=a; 30 printf(LL " ",now); 31 t=0; 32 } 33 else 34 { 35 now-=b; 36 printf(LL " ",now); 37 } 38 } 39 return 0; 40 }
bzoj3130
名字是费用流,结果是二分+网络流。。。dinic可以处理实数流量
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define maxn 110 9 #define maxm 1010 10 #define inf 1e+9 11 #define eps 1e-6 12 13 struct edge 14 { 15 int to; 16 double flow; 17 edge *next,*part; 18 }e[maxm<<1],*head[maxn]; 19 20 int n,m; 21 int ne=0,s,t; 22 int from[maxm],to[maxm]; 23 int q[maxn],d[maxn]; 24 double p; 25 double flow[maxm]; 26 27 inline void add(int from,int to,double flow) 28 { 29 e[ne].to=to; 30 e[ne].flow=flow; 31 e[ne].next=head[from]; 32 head[from]=&e[ne++]; 33 } 34 35 inline void add_edge(int from,int to,double flow) 36 { 37 e[ne].part=&e[ne+1]; 38 e[ne+1].part=&e[ne]; 39 add(from,to,flow); 40 add(to,from,0); 41 } 42 43 inline bool bfs() 44 { 45 int op=0,cls=1; 46 memset(d,-1,sizeof(d)); 47 q[1]=s; 48 d[s]=0; 49 while (op != cls) 50 { 51 int x=q[++op]; 52 for (edge *p=head[x];p;p=p->next) 53 if (p->flow > 0 && d[p->to] == -1) 54 { 55 d[p->to]=d[x]+1; 56 q[++cls]=p->to; 57 } 58 } 59 return d[t] != -1; 60 } 61 62 double dfs(int now,double now_flow) 63 { 64 if (now == t) 65 return now_flow; 66 double out=now_flow; 67 for (edge *p=head[now];p;p=p->next) 68 if (p->flow > 0 && d[p->to] == d[now]+1 && out > 0) 69 { 70 double f=dfs(p->to,fmin(p->flow,out)); 71 p->flow-=f; 72 p->part->flow+=f; 73 out-=f; 74 } 75 if (fabs(out-now_flow) < eps) 76 d[now]=-1; 77 return now_flow-out; 78 } 79 80 inline int dinic(double lim) 81 { 82 ne=0; 83 memset(head,0x0,sizeof(head)); 84 for (int i=1;i<=m;i++) 85 add_edge(from[i],to[i],fmin(flow[i],lim)); 86 double ans=0; 87 while (bfs()) 88 ans+=dfs(s,inf); 89 return ans; 90 } 91 92 int main() 93 { 94 scanf("%d%d%lf",&n,&m,&p); 95 s=1; 96 t=n; 97 double l=0,r=0; 98 for (int i=1;i<=m;i++) 99 { 100 scanf("%d%d%lf",&from[i],&to[i],&flow[i]); 101 r=fmax(flow[i],r); 102 } 103 r+=2; 104 double ans=0; 105 double max_flow=dinic(r); 106 for (int i=1;i<=30;i++) 107 { 108 double mid=(l+r)/2; 109 double now=dinic(mid); 110 if (fabs(now-max_flow) < eps) 111 { 112 ans=mid; 113 r=mid; 114 } 115 else 116 l=mid; 117 } 118 printf("%d\n",(int)(max_flow+1e-3)); 119 printf("%.4lf\n",ans*p); 120 return 0; 121 }
bzoj3142
自行百度奥赛辅导第八讲(例八)
1 #include <cstdio> 2 3 #ifdef unix 4 #define LL "%lld" 5 #else 6 #define LL "%I64d" 7 #endif 8 9 long long n,k,m,p; 10 11 long long pow(long long a,long long b) 12 { 13 long long wk=a,ans=1; 14 while (b) 15 { 16 if (b & 1) 17 (ans*=wk)%=p; 18 (wk*=wk)%=p; 19 b>>=1; 20 } 21 return ans; 22 } 23 24 int main() 25 { 26 scanf(LL LL LL LL,&n,&k,&m,&p); 27 n%=p; 28 long long ans=n*pow(m,k-1)%p-((m+1)*m/2)%p*(k-1)%p*pow(m,k-2)%p; 29 if (ans < 0) 30 ans+=p; 31 printf(LL,ans); 32 return 0; 33 }
bzoj3155(这都要隐藏?)
可以树状数组,我太弱了写了线段树
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 long long sum,lazy; 8 }t[maxn<<2]; 9 10 long long a[maxn]; 11 12 inline void _pushdown(long long l,long long r,long long rt) 13 { 14 if (t[rt].lazy) 15 { 16 long long add=t[rt].lazy,mid=(l+r)>>1; 17 t[rt<<1].lazy+=add; 18 t[rt<<1|1].lazy+=add; 19 t[rt<<1].sum+=add*(mid-l+1); 20 t[rt<<1|1].sum+=add*(r-mid); 21 t[rt].lazy=0; 22 } 23 } 24 25 inline void _update(long long rt) 26 { 27 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum; 28 } 29 30 void insert(long long l,long long r,long long rt,long long L,long long R,long long add) 31 { 32 if (l >= L && r <= R) 33 { 34 t[rt].sum+=(r-l+1)*add; 35 t[rt].lazy+=add; 36 return; 37 } 38 _pushdown(l,r,rt); 39 long long mid=(l+r)>>1; 40 if (L <= mid) 41 insert(l,mid,rt<<1,L,R,add); 42 if (R > mid) 43 insert(mid+1,r,rt<<1|1,L,R,add); 44 _update(rt); 45 } 46 47 long long query(long long l,long long r,long long rt,long long L,long long R) 48 { 49 if (l >= L && r <= R) 50 return t[rt].sum; 51 _pushdown(l,r,rt); 52 long long mid=(l+r)>>1,ans=0; 53 if (L <= mid) 54 ans+=query(l,mid,rt<<1,L,R); 55 if (R > mid) 56 ans+=query(mid+1,r,rt<<1|1,L,R); 57 return ans; 58 } 59 60 int main() 61 { 62 long long n,m; 63 scanf("%lld%lld",&n,&m); 64 long long now=0; 65 for (long long i=1;i<=n;i++) 66 { 67 scanf("%lld",&a[i]); 68 now+=a[i]; 69 insert(1,n,1,i,i,now); 70 } 71 for (long long i=1;i<=m;i++) 72 { 73 char s[10]; 74 scanf("%s",s); 75 if (s[0] == 'M') 76 { 77 long long x,y; 78 scanf("%lld%lld",&x,&y); 79 long long del=y-a[x]; 80 a[x]=y; 81 insert(1,n,1,x,n,del); 82 } 83 else 84 { 85 long long x; 86 scanf("%lld",&x); 87 printf("%lld\n",query(1,n,1,1,x)); 88 } 89 } 90 return 0; 91 }
bzoj3156(同上)
斜率优化的DP
1 #include <cstdio> 2 3 #define maxn 1000010 4 5 long long f[maxn],q[maxn],a[maxn]; 6 7 inline void read(long long &x) 8 { 9 char ch; 10 while (ch=getchar(),ch > '9' || ch < '0'); 11 x=ch-'0'; 12 while (ch=getchar(),ch <= '9' && ch >= '0') 13 x=(x<<3)+x+x+ch-'0'; 14 } 15 16 inline long long calc(long long a,long long b) 17 { 18 return f[a]-f[b]+(a*a+a-b*b-b)/2; 19 } 20 21 int main() 22 { 23 long long n; 24 read(n); 25 for (long long i=1;i<=n;i++) 26 read(a[i]); 27 long long op=0,cls=0; 28 for (long long i=1;i<=n;i++) 29 { 30 while (op < cls && calc(q[op+1],q[op]) <= i*(q[op+1]-q[op])) 31 op++; 32 f[i]=f[q[op]]+(i-q[op])*(i-q[op]-1)/2+a[i]; 33 while (op < cls && calc(i,q[cls])*(q[cls]-q[cls-1]) <= calc(q[cls],q[cls-1])*(i-q[cls])) 34 cls--; 35 q[++cls]=i; 36 } 37 printf("%lld\n",f[n]); 38 return 0; 39 }
bzoj3157(同上)
分治,把二项式展开有惊喜
1 #include <cstdio> 2 3 #define mod 1000000007 4 #define maxm 210 5 6 long long c[maxm][maxm]; 7 long long f[maxm][maxm]; 8 long long k; 9 10 long long pow(long long a,long long b) 11 { 12 long long ans=1; 13 for (;b;b>>=1) 14 { 15 if (b&1) 16 (ans*=a)%=mod; 17 (a*=a)%=mod; 18 } 19 return ans; 20 } 21 22 long long fdp(long long dep,long long n,long long m) 23 { 24 if (f[dep][m]) 25 return f[dep][m]; 26 if (!n) 27 return 0; 28 if (n&1) 29 f[dep][m]=pow(n,m)*pow(k,n)%mod; 30 n>>=1; 31 (f[dep][m]+=fdp(dep+1,n,m))%=mod; 32 long long now=0; 33 for (long long i=0;i<=m;i++) 34 (now+=c[m][i]*fdp(dep+1,n,i)%mod*pow(n,m-i))%=mod; 35 (now*=pow(k,n))%=mod; 36 (f[dep][m]+=now)%=mod; 37 return f[dep][m]; 38 } 39 40 int main() 41 { 42 long long n; 43 scanf("%lld%lld",&n,&k); 44 c[0][0]=1; 45 for (long long i=1;i<=k;i++) 46 { 47 c[i][0]=c[i][i]=1; 48 for (long long j=1;j<i;j++) 49 c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; 50 } 51 printf("%lld\n",fdp(0,n,k)); 52 return 0; 53 }
bzoj3158(noi完了之后到我写这篇日志的这段时间到底发生了什么。。。)
最小割模型
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define maxn 1010 9 #define maxm 1000010 10 #define s 0 11 #define t maxn-1 12 #define inf 0x3f3f3f3f 13 14 struct edge 15 { 16 int to,flow; 17 edge *next,*part; 18 }e[maxm<<1],*head[maxn]; 19 20 int ne=0; 21 int q[maxn],d[maxn]; 22 23 inline void add(int from,int to,int flow) 24 { 25 e[ne].flow=flow; 26 e[ne].to=to; 27 e[ne].next=head[from]; 28 head[from]=&e[ne++]; 29 } 30 31 inline void add_edge(int from,int to,int flow) 32 { 33 e[ne].part=&e[ne+1]; 34 e[ne+1].part=&e[ne]; 35 add(from,to,flow); 36 add(to,from,0); 37 } 38 39 inline bool bfs() 40 { 41 memset(d,-1,sizeof(d)); 42 int op=0,cls=1; 43 q[1]=s; 44 d[s]=0; 45 while (op != cls) 46 { 47 int x=q[++op]; 48 for (edge *p=head[x];p;p=p->next) 49 if (p->flow && d[p->to] == -1) 50 { 51 q[++cls]=p->to; 52 d[p->to]=d[x]+1; 53 } 54 } 55 return ~d[t]; 56 } 57 58 int dfs(int now,int now_flow) 59 { 60 if (now == t) 61 return now_flow; 62 int out=now_flow; 63 for (edge *p=head[now];p;p=p->next) 64 if (p->flow && d[p->to] == d[now]+1 && out) 65 { 66 int f=dfs(p->to,min(p->flow,out)); 67 p->flow-=f; 68 p->part->flow+=f; 69 out-=f; 70 } 71 if (out == now_flow) 72 d[now]=-1; 73 return now_flow-out; 74 } 75 76 inline int dinic() 77 { 78 int ans=0; 79 while (bfs()) 80 ans+=dfs(s,inf); 81 return ans; 82 } 83 84 inline bool check(int a,int b) 85 { 86 long long now=(long long)a*a+(long long)b*b; 87 int p=(int)sqrt(now+0.5); 88 if ((long long)p*p == now) 89 return 1; 90 return 0; 91 } 92 93 int a[maxn],b[maxn]; 94 95 int main() 96 { 97 int n; 98 scanf("%d",&n); 99 for (int i=1;i<=n;i++) 100 scanf("%d",&a[i]); 101 for (int i=1;i<=n;i++) 102 scanf("%d",&b[i]); 103 for (int i=1;i<=n;i++) 104 if (a[i]&1) 105 add_edge(i,t,b[i]); 106 else 107 add_edge(s,i,b[i]); 108 for (int i=1;i<=n;i++) 109 if (!(a[i]&1)) 110 for (int j=1;j<=n;j++) 111 if (a[j]&1 && __gcd(a[i],a[j]) == 1 && check(a[i],a[j])) 112 add_edge(i,j,inf); 113 int ans=0; 114 for (int i=1;i<=n;i++) 115 ans+=b[i]; 116 ans-=dinic(); 117 printf("%d\n",ans); 118 return 0; 119 }
bzoj3163
完全背包预处理,然后O(n)暴力合并,数据很水
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 #define maxn 1010 8 9 int n; 10 int a[maxn],b[maxn],c[maxn]; 11 int dp[maxn][maxn],fdp[maxn][maxn]; 12 int w[maxn*10],v[maxn*10]; 13 int f[maxn],numl[maxn],numr[maxn]; 14 15 inline void read(int &x) 16 { 17 char ch; 18 while (ch=getchar(),ch > '9' || ch < '0'); 19 x=ch-'0'; 20 while (ch=getchar(),ch <= '9' && ch >= '0') 21 x=(x<<3)+x+x+ch-'0'; 22 } 23 24 int main() 25 { 26 read(n); 27 for (int i=1;i<=n;i++) 28 { 29 read(a[i]); 30 read(b[i]); 31 read(c[i]); 32 } 33 int size=0; 34 for (int i=1;i<=n;i++) 35 { 36 numl[i]=size+1; 37 int now=c[i],wk=1,noww=b[i],nowv=a[i]; 38 while (now) 39 { 40 if (now < wk) 41 { 42 size++; 43 w[size]=b[i]*now; 44 v[size]=a[i]*now; 45 break; 46 } 47 size++; 48 w[size]=noww; 49 v[size]=nowv; 50 now-=wk; 51 wk<<=1; 52 noww<<=1; 53 nowv<<=1; 54 if (nowv > 1000) 55 break; 56 } 57 numr[i]=size; 58 } 59 int now=1; 60 for (int i=1;i<=size;i++) 61 { 62 for (int j=1000;j>=v[i];j--) 63 f[j]=max(f[j],f[j-v[i]]+w[i]); 64 if (numr[now] == i) 65 { 66 dp[now][0]=f[0]; 67 for (int j=1;j<=1000;j++) 68 dp[now][j]=max(f[j],dp[now][j-1]); 69 now++; 70 } 71 } 72 memset(f,0,sizeof(f)); 73 now=n; 74 for (int i=size;i;i--) 75 { 76 for (int j=1000;j>=v[i];j--) 77 f[j]=max(f[j],f[j-v[i]]+w[i]); 78 if (numl[now] == i) 79 { 80 fdp[now][0]=f[0]; 81 for (int j=1;j<=1000;j++) 82 fdp[now][j]=max(f[j],fdp[now][j-1]); 83 now--; 84 } 85 } 86 int _; 87 read(_); 88 while (_--) 89 { 90 int now,nowv,ans=0; 91 read(now); 92 read(nowv); 93 now++; 94 for (int i=0;i<=nowv;i++) 95 ans=max(ans,dp[now-1][i]+fdp[now+1][nowv-i]); 96 printf("%d\n",ans); 97 } 98 return 0; 99 }
bzoj3164
真是一道练读题能力的好题。。。读懂了就知道怎么做了
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 #define maxn 200010 8 #define inf 0x3f3f3f3f 9 10 struct edge 11 { 12 int to; 13 edge *next; 14 }e[maxn],*head[maxn]; 15 16 int size=0; 17 int d[maxn],dep[maxn],ne=0; 18 int point[maxn][2]; 19 int black[maxn],white[maxn]; 20 int fa[maxn],q[maxn]; 21 bool leaf[maxn]; 22 23 int dfs(int now,int col) 24 { 25 if (leaf[now]) 26 return d[now]=1; 27 if ((dep[now]&1) == col) 28 d[now]=inf; 29 else 30 d[now]=0; 31 for (edge *p=head[now];p;p=p->next) 32 { 33 dep[p->to]=dep[now]+1; 34 if ((dep[now]&1) == col) 35 d[now]=min(d[now],dfs(p->to,col)); 36 else 37 d[now]+=dfs(p->to,col); 38 } 39 return d[now]; 40 } 41 42 inline void bfs(int col) 43 { 44 int op=0,cls=1; 45 q[1]=1; 46 while (op != cls) 47 { 48 int x=q[++op]; 49 if (leaf[x]) 50 { 51 point[++size][col]=x; 52 continue; 53 } 54 for (edge *p=head[x];p;p=p->next) 55 { 56 if ((dep[x]&1) == col) 57 { 58 if (d[p->to] == d[x]) 59 q[++cls]=p->to; 60 } 61 else 62 q[++cls]=p->to; 63 } 64 } 65 } 66 67 inline void add_edge(int from,int to) 68 { 69 e[ne].to=to; 70 e[ne].next=head[from]; 71 head[from]=&e[ne++]; 72 } 73 74 int main() 75 { 76 int n; 77 scanf("%d",&n); 78 for (int i=1;i<=n;i++) 79 leaf[i]=1; 80 for (int i=2;i<=n;i++) 81 { 82 scanf("%d",&fa[i]); 83 add_edge(fa[i],i); 84 leaf[fa[i]]=0; 85 } 86 dep[1]=0; 87 d[1]=dfs(1,0); 88 bfs(0); 89 for (int i=1;i<=size;i++) 90 black[i]=point[i][0]; 91 int bsize=size; 92 memset(d,0,sizeof(d)); 93 size=0; 94 d[1]=dfs(1,1); 95 bfs(1); 96 int wsize=size; 97 for (int i=1;i<=size;i++) 98 white[i]=point[i][1]; 99 sort(black+1,black+bsize+1); 100 sort(white+1,white+wsize+1); 101 int nowb=1,noww=1; 102 int Min=0,ans=0,sum=0; 103 while (nowb <= bsize && noww <= wsize) 104 { 105 if (white[noww] == black[nowb]) 106 { 107 sum++; 108 ans^=white[noww]; 109 if (!Min) 110 Min=white[noww]; 111 noww++; 112 nowb++; 113 } 114 else 115 { 116 if (white[noww] < black[nowb]) 117 noww++; 118 else 119 nowb++; 120 } 121 } 122 printf("%d %d %d\n",Min,sum,ans); 123 return 0; 124 }
bzoj3166
处理出每个数前和后第二个比它大的位置,然后可持久化trie树
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 50010 7 8 struct Node 9 { 10 int size; 11 Node *s[2]; 12 }t[maxn*50],*root[maxn],null; 13 14 int _max; 15 int ne=0; 16 int n; 17 int a[maxn]; 18 int bit_mul[50]; 19 int pos[maxn]; 20 int l[maxn],r[maxn]; 21 int bit[maxn]; 22 23 inline void read(int &x) 24 { 25 char ch; 26 while (ch=getchar(),ch > '9' || ch < '0'); 27 x=ch-'0'; 28 while (ch=getchar(),ch <= '9' && ch >= '0') 29 x=(x<<3)+x+x+ch-'0'; 30 } 31 32 inline bool cmp(const int x,const int y) 33 { 34 return a[x] > a[y]; 35 } 36 37 inline Node* update(Node* pre,int val,int dep) 38 { 39 Node* now=&t[ne++]; 40 now->s[0]=pre->s[0]; 41 now->s[1]=pre->s[1]; 42 now->size=pre->size+1; 43 if (!dep) 44 return now; 45 if (val & bit_mul[dep-1]) 46 now->s[1]=update(pre->s[1],val,dep-1); 47 else 48 now->s[0]=update(pre->s[0],val,dep-1); 49 return now; 50 } 51 52 inline int query(int now) 53 { 54 int ans=0; 55 for (;now;now-=now&-now) 56 ans+=bit[now]; 57 return ans; 58 } 59 60 inline void bit_update(int now,int val) 61 { 62 for (;now<=n;now+=now&-now) 63 bit[now]+=val; 64 } 65 66 inline int find(int val) 67 { 68 int cnt=0,ans=0; 69 for (int i=_max;i>=0;i--) 70 { 71 ans+=bit_mul[i]; 72 if (ans > n || cnt+bit[ans] >= val) 73 ans-=bit_mul[i]; 74 else 75 cnt+=bit[ans]; 76 } 77 return ans+1; 78 } 79 80 inline int query(Node* L,Node* R,int val) 81 { 82 int ans=0,dep=31; 83 while (1) 84 { 85 if (!dep) 86 return ans; 87 bool d=(val&bit_mul[dep-1]) > 0; 88 if (R->s[d^1]->size-L->s[d^1]->size) 89 { 90 ans^=bit_mul[dep-1]; 91 R=R->s[d^1]; 92 L=L->s[d^1]; 93 } 94 else 95 { 96 R=R->s[d]; 97 L=L->s[d]; 98 } 99 dep--; 100 } 101 } 102 103 int main() 104 { 105 bit_mul[0]=1; 106 for (int i=1;i<=30;i++) 107 bit_mul[i]=bit_mul[i-1]+bit_mul[i-1]; 108 null.s[0]=null.s[1]=&null; 109 null.size=0; 110 root[0]=&null; 111 read(n); 112 for (int i=30;i;i--) 113 if (bit_mul[i] <= n) 114 { 115 _max=i; 116 break; 117 } 118 for (int i=1;i<=n;i++) 119 { 120 read(a[i]); 121 pos[i]=i; 122 } 123 sort(pos+1,pos+n+1,cmp); 124 for (int i=1;i<=n;i++) 125 root[i]=update(root[i-1],a[i],31); 126 for (int i=1;i<=n;i++) 127 { 128 int now=query(pos[i]); 129 if (now < 2) 130 l[pos[i]]=0; 131 else 132 l[pos[i]]=find(now-1); 133 if (now > i-3) 134 r[pos[i]]=n; 135 else 136 r[pos[i]]=find(now+2)-1; 137 bit_update(pos[i],1); 138 } 139 int ans=0; 140 for (int i=1;i<=n;i++) 141 ans=max(ans,query(root[l[i]],root[r[i]],a[i])); 142 printf("%d\n",ans); 143 return 0; 144 }
bzoj3170
把(x,y)转化成(x-y,x+y),然后该怎么做就怎么做吧
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 #define inf 0x3f3f3f3f3f3f3fLL 8 9 long long x[maxn],y[maxn]; 10 long long sumx[maxn],sumy[maxn]; 11 long long pos[maxn]; 12 13 inline bool cmp1(const long long a,const long long b) 14 { 15 return x[a] < x[b]; 16 } 17 18 inline bool cmp2(const long long a,const long long b) 19 { 20 return y[a] < y[b]; 21 } 22 23 int main() 24 { 25 long long n; 26 scanf("%lld",&n); 27 for (long long i=1;i<=n;i++) 28 { 29 long long a,b; 30 scanf("%lld%lld",&a,&b); 31 x[i]=a-b; 32 y[i]=a+b; 33 pos[i]=i; 34 } 35 sort(pos+1,pos+n+1,cmp1); 36 long long now=0; 37 for (long long i=2;i<=n;i++) 38 now+=x[pos[i]]-x[pos[1]]; 39 sumx[pos[1]]=now; 40 for (long long i=2;i<=n;i++) 41 { 42 now-=(x[pos[i]]-x[pos[i-1]])*(n-i+1); 43 now+=(x[pos[i]]-x[pos[i-1]])*(i-1); 44 sumx[pos[i]]=now; 45 } 46 sort(pos+1,pos+n+1,cmp2); 47 now=0; 48 for (long long i=2;i<=n;i++) 49 now+=y[pos[i]]-y[pos[1]]; 50 sumy[pos[1]]=now; 51 for (long long i=2;i<=n;i++) 52 { 53 now-=(y[pos[i]]-y[pos[i-1]])*(n-i+1); 54 now+=(y[pos[i]]-y[pos[i-1]])*(i-1); 55 sumy[pos[i]]=now; 56 } 57 long long _min=inf; 58 for (long long i=1;i<=n;i++) 59 if (sumx[i]+sumy[i] < _min) 60 _min=sumx[i]+sumy[i]; 61 printf("%lld\n",_min>>1); 62 return 0; 63 }
bzoj3171
等价于要让每个格子只有一个箭头指出去,并且只有一个箭头指向它,费用流
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 5010 8 #define maxm 200010 9 #define inf 0x3f3f3f3f 10 11 const int fx[]={-1,0,1,0}; 12 const int fy[]={0,1,0,-1}; 13 14 struct edge 15 { 16 int to,flow,cost; 17 edge *next,*part; 18 }e[maxm],*head[maxn],*prev[maxn]; 19 20 int s=0,t=maxn-1; 21 int ne=0; 22 int d[maxn],q[maxn]; 23 bool flag[maxn]; 24 25 inline bool spfa() 26 { 27 memset(d,0x3f,sizeof(d)); 28 memset(flag,0,sizeof(flag)); 29 int op=0,cls=1; 30 q[1]=s; 31 d[s]=0; 32 flag[s]=1; 33 while (op != cls) 34 { 35 op=op == maxn-1 ? 0 : op+1; 36 int x=q[op]; 37 for (edge *p=head[x];p;p=p->next) 38 if (p->flow && d[p->to] > d[x]+p->cost) 39 { 40 d[p->to]=d[x]+p->cost; 41 prev[p->to]=p->part; 42 if (!flag[p->to]) 43 { 44 if (op != cls) 45 { 46 int now=op == maxn-1 ? 0 : op+1; 47 if (d[p->to] < d[q[now]]) 48 { 49 q[op]=p->to; 50 op=op == 0 ? maxn-1 : op-1; 51 } 52 else 53 { 54 cls=cls == maxn-1 ? 0 : cls+1; 55 q[cls]=p->to; 56 } 57 } 58 else 59 { 60 cls=cls == maxn-1 ? 0 : cls+1; 61 q[cls]=p->to; 62 } 63 flag[p->to]=1; 64 } 65 } 66 flag[x]=0; 67 } 68 return d[t] != inf; 69 } 70 71 inline int agument() 72 { 73 int f=inf,ans=0; 74 for (edge *p=prev[t];p;p=prev[p->to]) 75 f=min(f,p->part->flow); 76 for (edge *p=prev[t];p;p=prev[p->to]) 77 { 78 p->flow+=f; 79 p->part->flow-=f; 80 ans+=p->part->cost*f; 81 } 82 return ans; 83 } 84 85 inline int min_cost() 86 { 87 int ans=0; 88 while (spfa()) 89 ans+=agument(); 90 return ans; 91 } 92 93 inline void add(int from,int to,int flow,int cost) 94 { 95 e[ne].to=to; 96 e[ne].flow=flow; 97 e[ne].cost=cost; 98 e[ne].next=head[from]; 99 head[from]=&e[ne++]; 100 } 101 102 inline void add_edge(int from,int to,int flow,int cost) 103 { 104 e[ne].part=&e[ne+1]; 105 e[ne+1].part=&e[ne]; 106 add(from,to,flow,cost); 107 add(to,from,0,-cost); 108 } 109 110 int map[16][16]; 111 112 int main() 113 { 114 int n,m; 115 scanf("%d%d",&n,&m); 116 for (int i=1;i<=n;i++) 117 for (int j=1;j<=m;j++) 118 { 119 char ch; 120 while (ch=getchar(),ch != 'R' && ch != 'L' && ch != 'U' && ch != 'D'); 121 if (ch == 'U') 122 map[i][j]=0; 123 if (ch == 'R') 124 map[i][j]=1; 125 if (ch == 'D') 126 map[i][j]=2; 127 if (ch == 'L') 128 map[i][j]=3; 129 } 130 for (int i=1;i<=n;i++) 131 for (int j=1;j<=m;j++) 132 { 133 add_edge(s,(i-1)*m+j,1,0); 134 add_edge((i-1)*m+j+n*m,t,1,0); 135 } 136 for (int i=1;i<=n;i++) 137 for (int j=1;j<=m;j++) 138 for (int k=0;k<4;k++) 139 { 140 int now=1; 141 if (k == map[i][j]) 142 now=0; 143 int nowx=i+fx[k],nowy=j+fy[k]; 144 if (nowx == 0) 145 nowx=n; 146 if (nowx == n+1) 147 nowx=1; 148 if (nowy == 0) 149 nowy=m; 150 if (nowy == m+1) 151 nowy=1; 152 add_edge((i-1)*m+j,(nowx-1)*m+nowy+n*m,1,now); 153 } 154 printf("%d\n",min_cost()); 155 return 0; 156 }
bzoj3172
写了一个要是在考场上会T的后缀数组。。。作死啊
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1500010 8 9 int n,maxl; 10 char ch[maxn]; 11 int s[maxn]; 12 int pos[maxn],l[maxn],sa[maxn]; 13 14 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 15 16 inline int cmp(int *r,int a,int b,int l) 17 {return r[a]==r[b]&&r[a+l]==r[b+l];} 18 19 inline void da(int *r,int *sa,int n,int m) 20 { 21 int i,j,p,*x=wa,*y=wb,*t; 22 for(i=0;i<m;i++) ws[i]=0; 23 for(i=0;i<n;i++) ws[x[i]=r[i]]++; 24 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 25 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 26 for(j=1,p=1;p<n;j*=2,m=p) 27 { 28 for(p=0,i=n-j;i<n;i++) y[p++]=i; 29 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 30 for(i=0;i<n;i++) wv[i]=x[y[i]]; 31 for(i=0;i<m;i++) ws[i]=0; 32 for(i=0;i<n;i++) ws[wv[i]]++; 33 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 34 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; 35 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 36 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 37 } 38 } 39 40 int rank[maxn],height[maxn]; 41 42 inline void calheight(int *r,int *sa,int n) 43 { 44 int i,j,k=0; 45 for(i=1;i<=n;i++) rank[sa[i]]=i; 46 for(i=0;i<n;height[rank[i++]]=k) 47 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 48 } 49 50 int bit[30]; 51 int f[maxn][22]; 52 53 inline void st_pre() 54 { 55 int l=lower_bound(bit,bit+25,maxl+1)-bit; 56 for (int i=1;i<=maxl;i++) 57 f[i][0]=height[i]; 58 for (int i=1;i<=l;i++) 59 for (int j=0;j+bit[i]<=maxl+1;j++) 60 f[j][i]=min(f[j][i-1],f[j+bit[i-1]][i-1]); 61 } 62 63 inline int query(int l,int r) 64 { 65 if (l == r) 66 return f[l][0]; 67 int len=lower_bound(bit,bit+25,r-l+1)-bit; 68 len--; 69 return min(f[l][len],f[r-bit[len]+1][len]); 70 } 71 72 inline int get_ans(int pos,int len) 73 { 74 int ans=0,now=0; 75 int l=0,r=pos; 76 if (height[pos] >= len) 77 { 78 while (l < r) 79 { 80 int mid=(l+r)>>1; 81 if (query(mid+1,pos) >= len) 82 { 83 now=pos-mid; 84 r=mid; 85 } 86 else 87 l=mid+1; 88 } 89 ans=now; 90 } 91 now=0; 92 if (height[pos+1] >= len) 93 { 94 l=pos+1,r=maxl+1; 95 while (l < r) 96 { 97 int mid=(l+r)>>1; 98 if (query(pos+1,mid) >= len) 99 { 100 now=mid-pos; 101 l=mid+1; 102 } 103 else 104 r=mid; 105 } 106 ans+=now; 107 } 108 return ans; 109 } 110 111 int main() 112 { 113 bit[0]=1; 114 for (int i=1;i<=25;i++) 115 bit[i]=bit[i-1]+bit[i-1]; 116 int now=0; 117 scanf("%d",&n); 118 for (int i=1;i<=n;i++) 119 { 120 scanf("%s",ch); 121 l[i]=strlen(ch); 122 pos[i]=now; 123 for (int j=0;j<l[i];j++) 124 s[now++]=ch[j]; 125 s[now++]='#'; 126 } 127 s[now]=0; 128 maxl=now; 129 da(s,sa,now+1,200); 130 calheight(s,sa,now); 131 st_pre(); 132 for (int i=1;i<=n;i++) 133 printf("%d\n",get_ans(rank[pos[i]],l[i])+1); 134 return 0; 135 }
bzoj3173
splay处理出最终序列,然后做最长上升序列
1 #include <cstdio> 2 3 #define maxn 100010 4 5 int cnt=0; 6 int a[maxn],pos[maxn]; 7 int t[maxn<<2]; 8 int f[maxn]; 9 10 inline int max(int a,int b) 11 { 12 return a > b ? a : b; 13 } 14 15 struct Node 16 { 17 int size,v; 18 Node *s[2],*par; 19 20 inline bool S() 21 { 22 return this == par->s[1]; 23 } 24 }; 25 26 struct splay 27 { 28 Node t[maxn],null; 29 Node *root; 30 int ne; 31 32 splay() 33 { 34 null.s[0]=null.s[1]=null.par=&null; 35 null.size=0; 36 null.v=0; 37 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2; 38 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1; 39 ne=2; 40 root=&t[0]; 41 } 42 43 inline void _update(Node* now) 44 { 45 now->size=now->s[0]->size+now->s[1]->size+1; 46 } 47 48 inline void _rot(Node* now) 49 { 50 Node* p=now->par; 51 int l=now->S(),r=!l; 52 (p->s[l]=now->s[r])->par=p; 53 now->par=p->par; 54 if (p->par != &null) 55 p->par->s[p->S()]=now; 56 (now->s[r]=p)->par=now; 57 _update(p); 58 _update(now); 59 } 60 61 inline void _splay(Node* now,Node* goal) 62 { 63 while (now->par != goal) 64 { 65 if (now->par->par == goal) 66 { 67 _rot(now); 68 break; 69 } 70 if (now->S() == now->par->S()) 71 { 72 _rot(now->par); 73 _rot(now); 74 } 75 else 76 { 77 _rot(now); 78 _rot(now); 79 } 80 } 81 if (goal == &null) 82 root=now; 83 } 84 85 inline Node* _select(int v) 86 { 87 Node* now=root; 88 while (1) 89 { 90 if (now->s[0]->size+1 == v) 91 return now; 92 if (v <= now->s[0]->size) 93 now=now->s[0]; 94 else 95 { 96 v-=now->s[0]->size+1; 97 now=now->s[1]; 98 } 99 } 100 } 101 102 inline void insert(int pos,int val) 103 { 104 Node* p=_select(pos+1); 105 Node* q=_select(pos+2); 106 _splay(p,&null); 107 _splay(q,root); 108 Node* now=&t[ne++]; 109 now->v=val; 110 now->size=1; 111 now->s[0]=now->s[1]=&null; 112 (q->s[0]=now)->par=q; 113 _update(q); 114 _update(p); 115 } 116 117 void travel(Node* now) 118 { 119 if (now->s[0] != &null) 120 travel(now->s[0]); 121 a[cnt]=now->v; 122 pos[now->v]=cnt; 123 cnt++; 124 if (now->s[1] != &null) 125 travel(now->s[1]); 126 } 127 }tree; 128 129 inline void update(int rt) 130 { 131 t[rt]=max(t[rt<<1],t[rt<<1|1]); 132 } 133 134 void change(int l,int r,int rt,int pos,int val) 135 { 136 if (l == r) 137 { 138 t[rt]=max(t[rt],val); 139 return; 140 } 141 int mid=(l+r)>>1; 142 if (pos <= mid) 143 change(l,mid,rt<<1,pos,val); 144 else 145 change(mid+1,r,rt<<1|1,pos,val); 146 update(rt); 147 } 148 149 int query(int l,int r,int rt,int L,int R) 150 { 151 if (l >= L && r <= R) 152 return t[rt]; 153 int mid=(l+r)>>1,ans=0; 154 if (L <= mid) 155 ans=max(ans,query(l,mid,rt<<1,L,R)); 156 if (R > mid) 157 ans=max(ans,query(mid+1,r,rt<<1|1,L,R)); 158 return ans; 159 } 160 161 int main() 162 { 163 int n; 164 scanf("%d",&n); 165 for (int i=1;i<=n;i++) 166 { 167 int x; 168 scanf("%d",&x); 169 tree.insert(x,i); 170 } 171 tree.travel(tree.root); 172 for (int i=1;i<=n;i++) 173 { 174 if (a[i] == 1) 175 f[i]=1; 176 else 177 f[i]=query(1,n,1,1,a[i]-1)+1; 178 change(1,n,1,a[i],f[i]); 179 } 180 int _max=0; 181 for (int i=1;i<=n;i++) 182 { 183 _max=max(_max,f[pos[i]]); 184 printf("%d\n",_max); 185 } 186 return 0; 187 }
bzoj3174
拯救矮人狙击手。。。两个数值相加为关键字排序之后DP
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 #define maxn 2010 8 9 int f[maxn][maxn]; 10 bool flag[maxn][maxn]; 11 int a[maxn],b[maxn],pos[maxn]; 12 13 inline bool cmp(const int x,const int y) 14 { 15 return a[x]+b[x] < a[y]+b[y]; 16 } 17 18 inline void read(int &x) 19 { 20 char ch; 21 while (ch=getchar(),ch > '9' || ch < '0'); 22 x=ch-'0'; 23 while (ch=getchar(),ch <= '9' && ch >= '0') 24 x=(x<<3)+x+x+ch-'0'; 25 } 26 27 int main() 28 { 29 memset(f,0,sizeof(f)); 30 memset(flag,0,sizeof(flag)); 31 int n,h,sum=0; 32 read(n); 33 for (int i=1;i<=n;i++) 34 { 35 read(a[i]); 36 read(b[i]); 37 sum+=a[i]; 38 pos[i]=i; 39 } 40 read(h); 41 sort(pos+1,pos+n+1,cmp); 42 f[0][0]=sum; 43 flag[0][0]=1; 44 for (int i=1;i<=n;i++) 45 for (int j=0;j<=i;j++) 46 { 47 int now=pos[i]; 48 f[i][j]=f[i-1][j]; 49 flag[i][j]=flag[i-1][j]; 50 if (f[i-1][j-1]+b[now] >= h && flag[i-1][j-1]) 51 { 52 f[i][j]=max(f[i][j],f[i-1][j-1]-a[now]); 53 flag[i][j]=1; 54 } 55 } 56 for (int i=n;i>=0;i--) 57 if (flag[n][i]) 58 { 59 printf("%d\n",i); 60 break; 61 } 62 return 0; 63 }
bzoj3175
水水的二分图最大独立集
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 50010 8 #define maxm 1000010 9 #define inf 0x3f3f3f3f 10 11 const int fx[]={2,1,-1,-2,2,1,-1,-2}; 12 const int fy[]={1,2,-2,-1,-1,-2,2,1}; 13 14 struct edge 15 { 16 int to,flow; 17 edge *next,*part; 18 }e[maxm],*head[maxn]; 19 20 int ne=0; 21 int s=0,t=maxn-1; 22 int d[maxn],q[maxn]; 23 24 inline void add(int from,int to,int flow) 25 { 26 e[ne].to=to; 27 e[ne].flow=flow; 28 e[ne].next=head[from]; 29 head[from]=&e[ne++]; 30 } 31 32 inline void add_edge(int from,int to,int flow) 33 { 34 e[ne].part=&e[ne+1]; 35 e[ne+1].part=&e[ne]; 36 add(from,to,flow); 37 add(to,from,0); 38 } 39 40 inline bool bfs() 41 { 42 memset(d,-1,sizeof(d)); 43 int op=0,cls=1; 44 q[1]=s; 45 d[s]=0; 46 while (op != cls) 47 { 48 int x=q[++op]; 49 for (edge *p=head[x];p;p=p->next) 50 if (p->flow && d[p->to] == -1) 51 { 52 d[p->to]=d[x]+1; 53 q[++cls]=p->to; 54 } 55 } 56 return d[t] != -1; 57 } 58 59 int dfs(int now,int now_flow) 60 { 61 if (now == t) 62 return now_flow; 63 int out=now_flow; 64 for (edge *p=head[now];p;p=p->next) 65 if (p->flow && d[p->to] == d[now]+1 && out) 66 { 67 int f=dfs(p->to,min(p->flow,out)); 68 p->flow-=f; 69 p->part->flow+=f; 70 out-=f; 71 } 72 if (out == now_flow) 73 d[now]=-1; 74 return now_flow-out; 75 } 76 77 inline int dinic() 78 { 79 int ans=0; 80 while (bfs()) 81 ans+=dfs(s,inf); 82 return ans; 83 } 84 85 int map[210][210]; 86 87 int main() 88 { 89 int n; 90 scanf("%d",&n); 91 for (int i=1;i<=n;i++) 92 for (int j=1;j<=n;j++) 93 { 94 char ch; 95 while (ch=getchar(),ch != '0' && ch != '1'); 96 if (ch == '0') 97 map[i][j]=1; 98 else 99 map[i][j]=0; 100 } 101 int sum=0; 102 for (int i=1;i<=n;i++) 103 for (int j=1;j<=n;j++) 104 if (map[i][j]) 105 { 106 map[i][j]=++sum; 107 if ((i+j)&1) 108 add_edge(sum,t,1); 109 else 110 add_edge(s,sum,1); 111 } 112 for (int i=1;i<=n;i++) 113 for (int j=1;j<=n;j++) 114 if (map[i][j] && !((i+j)&1)) 115 for (int k=0;k<8;k++) 116 { 117 int nowx=i+fx[k],nowy=j+fy[k]; 118 if (nowx >= 1 && nowx <= n && nowy >= 1 && nowy <= n && map[nowx][nowy]) 119 add_edge(map[i][j],map[nowx][nowy],inf); 120 } 121 printf("%d\n",sum-dinic()); 122 return 0; 123 }
bzoj3190
还记得水平可见直线吗?加一条直线就可以了
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 10010 8 #define inf 0x3f3f3f3fLL 9 #define eps 1e-6 10 11 struct line 12 { 13 long long k,b,num; 14 15 inline bool operator < (const line x) const 16 { 17 return (k < x.k) || (k == x.k && b > x.b); 18 } 19 }a[maxn]; 20 21 long long sta[maxn]; 22 long long ans[maxn]; 23 24 inline bool check(int x,int y,int z) 25 { 26 return (a[x].b-a[y].b)*(a[z].k-a[y].k) > (a[y].b-a[z].b)*(a[y].k-a[x].k); 27 } 28 29 int main() 30 { 31 long long n,_max=0; 32 scanf("%lld",&n); 33 for (long long i=1;i<=n;i++) 34 { 35 scanf("%lld",&a[i].b); 36 if (a[i].b > _max) 37 _max=a[i].b; 38 a[i].num=i; 39 } 40 for (long long i=1;i<=n;i++) 41 scanf("%lld",&a[i].k); 42 a[0].k=-inf; 43 a[0].b=_max; 44 a[0].num=0; 45 sort(a,a+n+1); 46 long long top=1; 47 sta[top]=0; 48 for (long long i=1;i<=n;i++) 49 { 50 if (a[i].k == a[sta[top]].k) 51 { 52 if (a[i].b < a[sta[top]].b) 53 continue; 54 else 55 sta[++top]=i; 56 } 57 else 58 { 59 if (top < 2) 60 sta[++top]=i; 61 else 62 { 63 while (top >= 2 && check(sta[top-1],sta[top],i)) 64 top--; 65 sta[++top]=i; 66 } 67 } 68 } 69 long long cnt=0; 70 for (long long i=1;i<=top;i++) 71 if (a[sta[i]].num) 72 ans[++cnt]=a[sta[i]].num; 73 sort(ans+1,ans+cnt+1); 74 printf("%lld\n",cnt); 75 for (long long i=1;i<cnt;i++) 76 printf("%lld ",ans[i]); 77 printf("%lld",ans[cnt]); 78 return 0; 79 }
bzoj3192
曾经想用splay来暴力,直到zhx神犇给我讲了正解。。。确实是一个树状数组就能解决的问题
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 long long n,n1,n2; 9 long long bit[maxn],a[maxn],pos[maxn]; 10 11 inline bool cmp(const long long x,const long long y) 12 { 13 return a[x] > a[y]; 14 } 15 16 inline void bit_update(long long now,long long val) 17 { 18 for (;now<=n;now+=now & -now) 19 bit[now]+=val; 20 } 21 22 inline long long query(long long now) 23 { 24 long long ans=0; 25 for (;now;now-=now & -now) 26 ans+=bit[now]; 27 return ans; 28 } 29 30 int main() 31 { 32 scanf("%lld%lld",&n1,&n2); 33 n=n1+n2; 34 for (long long i=n1;i;i--) 35 scanf("%lld",&a[i]); 36 for (long long i=n1+1;i<=n;i++) 37 scanf("%lld",&a[i]); 38 for (long long i=1;i<=n;i++) 39 pos[i]=i; 40 sort(pos+1,pos+n+1,cmp); 41 for (long long i=1;i<=n;i++) 42 bit_update(i,1); 43 long long now=n1,ans=0; 44 for (long long i=1;i<=n;i++) 45 { 46 long long p=pos[i]; 47 if (p <= now) 48 { 49 ans+=query(now)-query(p); 50 now=p-1; 51 } 52 else 53 { 54 ans+=query(p)-query(now)-1; 55 now=p-1; 56 } 57 bit_update(p,-1); 58 } 59 printf("%lld\n",ans); 60 return 0; 61 }
bzoj3196
据说树套树复杂度很高(其实是我不会),然后就写了树状数组套主席树,不小心又rank1了。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 50010 7 8 struct Node 9 { 10 int size; 11 Node* s[2]; 12 }t[maxn*100],*root[maxn],*L[30],*R[30],null; 13 14 int n; 15 int ne=0; 16 int lsize,rsize; 17 int size; 18 19 inline Node* new_Node() 20 { 21 Node* now=&t[ne++]; 22 now->s[0]=now->s[1]=&null; 23 now->size=0; 24 return now; 25 } 26 27 inline void read(int &x) 28 { 29 char ch; 30 bool flag=0; 31 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-')); 32 if (ch == '-') 33 flag=1; 34 else 35 x=ch-'0'; 36 while (ch=getchar(),ch <= '9' && ch >= '0') 37 x=(x<<3)+x+x+ch-'0'; 38 if (flag) 39 x=-x; 40 } 41 42 inline int Rank(int v,int flag) 43 { 44 int l=1,r=size,ans=0; 45 while (1) 46 { 47 if (l == r) 48 { 49 if (!flag) 50 return ans; 51 for (int i=1;i<=lsize;i++) 52 ans-=L[i]->size; 53 for (int i=1;i<=rsize;i++) 54 ans+=R[i]->size; 55 return ans+1; 56 } 57 int mid=(l+r)>>1; 58 if (v <= mid) 59 { 60 for (int i=1;i<=lsize;i++) 61 L[i]=L[i]->s[0]; 62 for (int i=1;i<=rsize;i++) 63 R[i]=R[i]->s[0]; 64 r=mid; 65 } 66 else 67 { 68 for (int i=1;i<=lsize;i++) 69 { 70 ans-=L[i]->s[0]->size; 71 L[i]=L[i]->s[1]; 72 } 73 for (int i=1;i<=rsize;i++) 74 { 75 ans+=R[i]->s[0]->size; 76 R[i]=R[i]->s[1]; 77 } 78 l=mid+1; 79 } 80 } 81 } 82 83 inline int get_Rank(int l,int r,int v) 84 { 85 lsize=rsize=0; 86 for (;l;l-=l&-l) 87 L[++lsize]=root[l]; 88 for (;r;r-=r&-r) 89 R[++rsize]=root[r]; 90 return Rank(v,0); 91 } 92 93 inline int query(int k) 94 { 95 int l=1,r=size; 96 while (1) 97 { 98 if (l == r) 99 return l; 100 int del=0,mid=(l+r)>>1; 101 for (int i=1;i<=lsize;i++) 102 del-=L[i]->s[0]->size; 103 for (int i=1;i<=rsize;i++) 104 del+=R[i]->s[0]->size; 105 if (k <= del) 106 { 107 for (int i=1;i<=lsize;i++) 108 L[i]=L[i]->s[0]; 109 for (int i=1;i<=rsize;i++) 110 R[i]=R[i]->s[0]; 111 r=mid; 112 } 113 else 114 { 115 for (int i=1;i<=lsize;i++) 116 L[i]=L[i]->s[1]; 117 for (int i=1;i<=rsize;i++) 118 R[i]=R[i]->s[1]; 119 l=mid+1; 120 k-=del; 121 } 122 } 123 } 124 125 inline int ask(int l,int r,int k) 126 { 127 lsize=rsize=0; 128 for (;l;l-=l&-l) 129 L[++lsize]=root[l]; 130 for (;r;r-=r&-r) 131 R[++rsize]=root[r]; 132 return query(k); 133 } 134 135 inline int pred(int l,int r,int v) 136 { 137 lsize=rsize=0; 138 for (int i=l;i;i-=i&-i) 139 L[++lsize]=root[i]; 140 for (int i=r;i;i-=i&-i) 141 R[++rsize]=root[i]; 142 int k=Rank(v,0); 143 return ask(l,r,k); 144 } 145 146 inline int succ(int l,int r,int v) 147 { 148 lsize=rsize=0; 149 for (int i=l;i;i-=i&-i) 150 L[++lsize]=root[i]; 151 for (int i=r;i;i-=i&-i) 152 R[++rsize]=root[i]; 153 int k=Rank(v,1); 154 return ask(l,r,k); 155 } 156 157 inline void update(Node* now,int val,int add) 158 { 159 int l=1,r=size; 160 while (1) 161 { 162 now->size+=add; 163 if (l == r) 164 return; 165 int mid=(l+r)>>1; 166 if (val <= mid) 167 { 168 if (now->s[0] == &null) 169 now->s[0]=new_Node(); 170 now=now->s[0]; 171 r=mid; 172 } 173 else 174 { 175 if (now->s[1] == &null) 176 now->s[1]=new_Node(); 177 now=now->s[1]; 178 l=mid+1; 179 } 180 } 181 } 182 183 inline void bit_update(int pos,int val,int add) 184 { 185 for (;pos<=n;pos+=pos&-pos) 186 update(root[pos],val,add); 187 } 188 189 int a[maxn],b[maxn<<1]; 190 int q[maxn],x[maxn],y[maxn],z[maxn]; 191 192 int main() 193 { 194 int m; 195 read(n); 196 read(m); 197 for (int i=1;i<=n;i++) 198 { 199 read(a[i]); 200 b[i]=a[i]; 201 } 202 size=n; 203 for (int i=1;i<=m;i++) 204 { 205 read(q[i]); 206 if (q[i] == 3) 207 { 208 read(x[i]); 209 read(y[i]); 210 b[++size]=y[i]; 211 } 212 else 213 { 214 read(x[i]); 215 read(y[i]); 216 read(z[i]); 217 if (q[i] != 2) 218 b[++size]=z[i]; 219 } 220 } 221 sort(b+1,b+size+1); 222 size=unique(b+1,b+size+1)-b-1; 223 for (int i=1;i<=n;i++) 224 a[i]=lower_bound(b+1,b+size+1,a[i])-b; 225 null.s[0]=null.s[1]=&null; 226 null.size=0; 227 root[0]=&null; 228 for (int i=1;i<=n;i++) 229 root[i]=new_Node(); 230 for (int i=1;i<=n;i++) 231 bit_update(i,a[i],1); 232 for (int i=1;i<=m;i++) 233 { 234 if (q[i] == 1) 235 { 236 z[i]=lower_bound(b+1,b+size+1,z[i])-b; 237 printf("%d\n",get_Rank(x[i]-1,y[i],z[i])+1); 238 } 239 if (q[i] == 2) 240 printf("%d\n",b[ask(x[i]-1,y[i],z[i])]); 241 if (q[i] == 3) 242 { 243 y[i]=lower_bound(b+1,b+size+1,y[i])-b; 244 bit_update(x[i],a[x[i]],-1); 245 a[x[i]]=y[i]; 246 bit_update(x[i],a[x[i]],1); 247 } 248 if (q[i] == 4) 249 { 250 z[i]=lower_bound(b+1,b+size+1,z[i])-b; 251 printf("%d\n",b[pred(x[i]-1,y[i],z[i])]); 252 } 253 if (q[i] == 5) 254 { 255 z[i]=lower_bound(b+1,b+size+1,z[i])-b; 256 printf("%d\n",b[succ(x[i]-1,y[i],z[i])]); 257 } 258 } 259 return 0; 260 }
bzoj3207
hash+主席树这种神级常数的写法一定只有我这个,b才会写。。。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 #define mod 200003LL 8 9 typedef long long ll; 10 typedef unsigned long long ull; 11 12 struct Node 13 { 14 int size; 15 Node *s[2]; 16 17 Node() 18 { 19 size=0; 20 } 21 }t[maxn*30],*root[maxn],null; 22 23 int ne=0; 24 ull bit[50]; 25 int size1=0,size2=0; 26 int san1[maxn*10]; 27 ull san2[maxn*10]; 28 int ql[maxn],qr[maxn]; 29 int q[maxn][25]; 30 int a[maxn]; 31 ull hash[maxn],qhash[maxn]; 32 33 Node* update(Node* pre,ull l,ull r,ull val) 34 { 35 Node* now=&t[ne++]; 36 now->s[0]=pre->s[0]; 37 now->s[1]=pre->s[1]; 38 now->size=pre->size+1; 39 if (l == r) 40 return now; 41 ull mid=(l+r)>>1; 42 if (val <= mid) 43 now->s[0]=update(pre->s[0],l,mid,val); 44 else 45 now->s[1]=update(pre->s[1],mid+1,r,val); 46 return now; 47 } 48 49 inline bool query(Node* L,Node* R,ull l,ull r,ull val) 50 { 51 while (1) 52 { 53 if (l == r) 54 { 55 if (R->size-L->size) 56 return 1; 57 else 58 return 0; 59 } 60 if (R->size-L->size == 0) 61 return 0; 62 ull mid=(l+r)>>1; 63 if (val <= mid) 64 { 65 L=L->s[0]; 66 R=R->s[0]; 67 r=mid; 68 } 69 else 70 { 71 L=L->s[1]; 72 R=R->s[1]; 73 l=mid+1; 74 } 75 } 76 } 77 78 inline void read(int &x) 79 { 80 char ch; 81 while (ch=getchar(),ch > '9' || ch < '0'); 82 x=ch-'0'; 83 while (ch=getchar(),ch <= '9' && ch >= '0') 84 x=(x<<3)+x+x+ch-'0'; 85 } 86 87 int main() 88 { 89 null.s[0]=null.s[1]=&null; 90 int n,m,k; 91 read(n); 92 read(m); 93 read(k); 94 bit[0]=1; 95 for (int i=1;i<=k+10;i++) 96 bit[i]=bit[i-1]*mod; 97 for (int i=1;i<=n;i++) 98 { 99 read(a[i]); 100 san1[++size1]=a[i]; 101 } 102 for (int i=1;i<=m;i++) 103 { 104 read(ql[i]); 105 read(qr[i]); 106 for (int j=1;j<=k;j++) 107 { 108 read(q[i][j]); 109 san1[++size1]=q[i][j]; 110 } 111 } 112 sort(san1+1,san1+size1+1); 113 size1=unique(san1+1,san1+size1+1)-san1-1; 114 for (int i=1;i<=n;i++) 115 a[i]=lower_bound(san1+1,san1+size1+1,a[i])-san1; 116 for (int i=1;i<=m;i++) 117 for (int j=1;j<=k;j++) 118 q[i][j]=lower_bound(san1+1,san1+size1+1,q[i][j])-san1; 119 ull now_hash=0; 120 for (int i=1;i<=k;i++) 121 now_hash=now_hash*mod+a[i]; 122 hash[1]=san2[++size2]=now_hash; 123 for (int i=k+1;i<=n;i++) 124 { 125 now_hash*=mod; 126 now_hash-=a[i-k]*bit[k]; 127 now_hash+=a[i]; 128 hash[i-k+1]=san2[++size2]=now_hash; 129 } 130 for (int i=1;i<=m;i++) 131 { 132 now_hash=0; 133 for (int j=1;j<=k;j++) 134 now_hash=now_hash*mod+q[i][j]; 135 qhash[i]=san2[++size2]=now_hash; 136 } 137 sort(san2+1,san2+size2+1); 138 size2=unique(san2+1,san2+size2+1)-san2-1; 139 for (int i=1;i<=n-k+1;i++) 140 hash[i]=lower_bound(san2+1,san2+size2+1,hash[i])-san2; 141 for (int i=1;i<=m;i++) 142 qhash[i]=lower_bound(san2+1,san2+size2+1,qhash[i])-san2; 143 root[0]=&null; 144 for (int i=1;i<=n-k+1;i++) 145 root[i]=update(root[i-1],1,size2,hash[i]); 146 for (int i=1;i<=m;i++) 147 { 148 int now=query(root[ql[i]-1],root[qr[i]-k+1],1,size2,qhash[i]); 149 if (now) 150 puts("No"); 151 else 152 puts("Yes"); 153 } 154 return 0; 155 }
bzoj3209
数位DP,想象成树形
1 #include <cstdio> 2 3 #define maxn 70 4 #define mod 10000007 5 6 long long f[maxn][maxn]; 7 long long bit[maxn]; 8 9 inline long long pow(long long a,long long b) 10 { 11 long long ans=1,wk=a; 12 for (;b;b>>=1) 13 { 14 if (b&1) 15 (ans*=wk)%=mod; 16 (wk*=wk)%=mod; 17 } 18 return ans; 19 } 20 21 inline long long calc(long long n,long long k) 22 { 23 long long now=0,ans=0; 24 for (long long i=60;i;i--) 25 { 26 if (n&bit[i]) 27 { 28 now++; 29 if (now > k) 30 break; 31 n^=bit[i]; 32 } 33 if (n&bit[i-1]) 34 ans+=f[i-1][k-now]; 35 } 36 if (now+n == k) 37 ans++; 38 return ans; 39 } 40 41 int main() 42 { 43 f[0][0]=1; 44 bit[0]=1; 45 for (long long i=1;i<=60;i++) 46 { 47 bit[i]=bit[i-1]*2; 48 f[i][0]=f[i-1][0]; 49 for (long long j=1;j<=i;j++) 50 f[i][j]=f[i-1][j]+f[i-1][j-1]; 51 } 52 long long n,ans=1; 53 scanf("%lld",&n); 54 for (long long i=2;i<=60;i++) 55 (ans*=pow(i,calc(n,i)))%=mod; 56 printf("%lld\n",ans); 57 return 0; 58 }
bzoj3211
spoj的gss4,注意本来就是0的也是不会变成1的
1 #include <cstdio> 2 #include <cmath> 3 4 #define maxn 100010 5 6 int n; 7 long long bit[maxn]; 8 int a[maxn]; 9 int f[maxn]; 10 11 int find(int x) 12 { 13 if (f[x] == x) 14 return x; 15 return f[x]=find(f[x]); 16 } 17 18 inline void bit_update(int pos,int val) 19 { 20 for (;pos<=n;pos+=pos&-pos) 21 bit[pos]+=val; 22 } 23 24 inline long long query(int x) 25 { 26 long long ans=0; 27 for (;x;x-=x&-x) 28 ans+=bit[x]; 29 return ans; 30 } 31 32 inline void read(int &x) 33 { 34 char ch; 35 while (ch=getchar(),ch > '9' || ch < '0'); 36 x=ch-'0'; 37 while (ch=getchar(),ch <= '9' && ch >= '0') 38 x=(x<<3)+x+x+ch-'0'; 39 } 40 41 int main() 42 { 43 read(n); 44 for (int i=1;i<=n;i++) 45 { 46 read(a[i]); 47 bit_update(i,a[i]); 48 if (a[i] <= 1) 49 f[i]=i+1; 50 else 51 f[i]=i; 52 } 53 f[n+1]=n+1; 54 int _; 55 read(_); 56 while (_--) 57 { 58 int x,l,r; 59 read(x); 60 read(l); 61 read(r); 62 if (x == 1) 63 printf("%lld\n",query(r)-query(l-1)); 64 else 65 { 66 for (int i=find(l);i<=r;i=find(i+1)) 67 if (a[i] > 1) 68 { 69 int x=(int)sqrt(a[i]+0.5); 70 bit_update(i,x-a[i]); 71 a[i]=x; 72 if (a[i] <= 1 && f[i] == i) 73 f[i]=i+1; 74 } 75 } 76 } 77 return 0; 78 }
bzoj3212
可以树状数组,太弱了只能写线段树。。。
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 long long sum,lazy; 8 }t[maxn<<2]; 9 10 inline void _pushdown(long long l,long long r,long long rt) 11 { 12 if (t[rt].lazy) 13 { 14 long long mid=(l+r)>>1,add=t[rt].lazy; 15 t[rt<<1].lazy+=add; 16 t[rt<<1|1].lazy+=add; 17 t[rt<<1].sum+=add*(mid-l+1); 18 t[rt<<1|1].sum+=add*(r-mid); 19 t[rt].lazy=0; 20 } 21 } 22 23 inline void _update(long long rt) 24 { 25 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum; 26 } 27 28 void insert(long long l,long long r,long long rt,long long L,long long R,long long add) 29 { 30 if (l >= L && r <= R) 31 { 32 t[rt].lazy+=add; 33 t[rt].sum+=(r-l+1)*add; 34 return; 35 } 36 _pushdown(l,r,rt); 37 long long mid=(l+r)>>1; 38 if (L <= mid) 39 insert(l,mid,rt<<1,L,R,add); 40 if (R > mid) 41 insert(mid+1,r,rt<<1|1,L,R,add); 42 _update(rt); 43 } 44 45 long long query(long long l,long long r,long long rt,long long L,long long R) 46 { 47 if (l >= L && r <= R) 48 return t[rt].sum; 49 _pushdown(l,r,rt); 50 long long mid=(l+r)>>1,ans=0; 51 if (L <= mid) 52 ans+=query(l,mid,rt<<1,L,R); 53 if (R > mid) 54 ans+=query(mid+1,r,rt<<1|1,L,R); 55 return ans; 56 } 57 58 void build(long long l,long long r,long long rt) 59 { 60 t[rt].lazy=0; 61 if (l == r) 62 { 63 scanf("%lld",&t[rt].sum); 64 return; 65 } 66 long long mid=(l+r)>>1; 67 build(l,mid,rt<<1); 68 build(mid+1,r,rt<<1|1); 69 _update(rt); 70 } 71 72 int main() 73 { 74 long long n,_; 75 scanf("%lld",&n); 76 scanf("%lld",&_); 77 build(1,n,1); 78 while (_--) 79 { 80 char s[2]; 81 long long x,y,z; 82 scanf("%s",s); 83 if (s[0] == 'Q') 84 { 85 scanf("%lld%lld",&x,&y); 86 printf("%lld\n",query(1,n,1,x,y)); 87 } 88 else 89 { 90 scanf("%lld%lld%lld",&x,&y,&z); 91 insert(1,n,1,x,y,z); 92 } 93 } 94 return 0; 95 }
bzoj3214
就是一模拟+暴力
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 1000010 8 #define inf 0x3f3f3f3f 9 10 int a[4][maxn]; 11 int l[4]; 12 int pos[maxn]; 13 14 int main() 15 { 16 // freopen("1.in","r",stdin); 17 // freopen("1.out","w",stdout); 18 for (int i=0;i<4;i++) 19 { 20 static char s[maxn]; 21 char ch; 22 gets(s); 23 int len=strlen(s),p=0; 24 while (p < len) 25 { 26 while (ch=s[p++],ch < 'a' || ch > 'z'); 27 a[i][++l[i]]=ch-'a'+1; 28 while (ch=s[p++],ch >= 'a' && ch <= 'z') 29 a[i][l[i]]=a[i][l[i]]*28+ch-'a'+1; 30 } 31 } 32 int nowl=1,nowr=l[0],p=1,ans=0; 33 while (p <= l[1]) 34 { 35 if (a[0][nowl] == a[1][p]) 36 p++; 37 else 38 ans++; 39 nowl++; 40 } 41 p=l[3]; 42 while (p) 43 { 44 if (a[0][nowr] == a[3][p]) 45 p--; 46 else 47 ans++; 48 nowr--; 49 } 50 int cnt=0; 51 for (int i=nowl;i<=nowr;i++) 52 if (a[0][i] == a[2][1]) 53 pos[++cnt]=i; 54 int _min=inf; 55 for (int i=1;i<=cnt;i++) 56 { 57 int now=0; 58 p=1; 59 while (pos[i] <= nowr && p <= l[2]) 60 { 61 if (a[0][pos[i]] == a[2][p]) 62 p++; 63 else 64 now++; 65 pos[i]++; 66 } 67 if (p > l[2]) 68 _min=min(_min,now); 69 } 70 printf("%d\n",ans+_min); 71 return 0; 72 }
bzoj3223
splay维护,也可以块链
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 struct Node 9 { 10 int v,size; 11 bool rot; 12 Node *par,*s[2]; 13 14 inline bool S() 15 { 16 return this == par->s[1]; 17 } 18 }; 19 20 struct splay 21 { 22 Node t[maxn],null; 23 Node *root; 24 int ne; 25 26 inline splay() 27 { 28 null.s[0]=null.s[1]=null.par=&null;null.size=0; 29 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2; 30 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1; 31 root=&t[0]; 32 ne=2; 33 } 34 35 inline void _update(Node* now) 36 { 37 now->size=now->s[0]->size+now->s[1]->size+1; 38 } 39 40 inline void _pushdown(Node* now) 41 { 42 if (now->rot) 43 { 44 now->rot^=1; 45 now->s[0]->rot^=1; 46 now->s[1]->rot^=1; 47 swap(now->s[0],now->s[1]); 48 } 49 } 50 51 inline void _rot(Node* now) 52 { 53 Node* p=now->par; 54 bool l=now->S(),r=!l; 55 (p->s[l]=now->s[r])->par=p; 56 now->par=p->par; 57 if (p->par != &null) 58 p->par->s[p->S()]=now; 59 (now->s[r]=p)->par=now; 60 _update(p); 61 _update(now); 62 } 63 64 inline void _splay(Node* now,Node* goal) 65 { 66 while (now->par != goal) 67 { 68 if (now->par->par == goal) 69 { 70 _rot(now); 71 break; 72 } 73 if (now->S() == now->par->S()) 74 { 75 _rot(now->par); 76 _rot(now); 77 } 78 else 79 { 80 _rot(now); 81 _rot(now); 82 } 83 } 84 if (goal == &null) 85 root=now; 86 } 87 88 Node* build(int l,int r,Node* par,bool d) 89 { 90 if (l > r) 91 return &null; 92 int mid=(l+r)>>1; 93 Node* now=&t[ne++]; 94 now->v=mid; 95 (par->s[d]=now)->par=par; 96 now->s[0]=build(l,mid-1,now,0); 97 now->s[1]=build(mid+1,r,now,1); 98 _update(now); 99 return now; 100 } 101 102 inline Node* _select(int v) 103 { 104 Node* now=root; 105 while (v) 106 { 107 _pushdown(now); 108 if (now->s[0]->size+1 == v) 109 return now; 110 if (v <= now->s[0]->size) 111 now=now->s[0]; 112 else 113 { 114 v-=now->s[0]->size+1; 115 now=now->s[1]; 116 } 117 } 118 } 119 120 inline void rot(int l,int r) 121 { 122 Node* p=_select(l); 123 _splay(p,&null); 124 Node* q=_select(r+2); 125 _splay(q,root); 126 q->s[0]->rot^=1; 127 } 128 129 void travel(Node* now) 130 { 131 _pushdown(now); 132 if (now->s[0] != &null) 133 travel(now->s[0]); 134 if (now != &t[0] && now != &t[1]) 135 printf("%d ",now->v); 136 if (now->s[1] != &null) 137 travel(now->s[1]); 138 } 139 }t; 140 141 inline void read(int &x) 142 { 143 char ch; 144 while (ch=getchar(),ch > '9' || ch < '0'); 145 x=ch-'0'; 146 while (ch=getchar(),ch <= '9' && ch >= '0') 147 x=(x<<3)+x+x+ch-'0'; 148 } 149 150 int main() 151 { 152 int n,m; 153 read(n); 154 read(m); 155 t.build(1,n,&t.t[1],0); 156 t._update(&t.t[1]); 157 t._update(&t.t[0]); 158 while (m--) 159 { 160 int x,y; 161 read(x); 162 read(y); 163 t.rot(x,y); 164 } 165 t.travel(t.root); 166 return 0; 167 }
bzoj3224
平衡树维护(注意删除的数可能不存在。。。坑爹的bzoj),也可以用树状数组
1 #include <cstdio> 2 3 #define maxn 100010 4 5 struct Node 6 { 7 int size,v; 8 Node *s[2]; 9 }; 10 11 struct sbt 12 { 13 Node t[maxn],null; 14 Node *root; 15 int ne; 16 17 inline sbt() 18 { 19 null.s[0]=null.s[1]=&null; 20 root=&null; 21 ne=0; 22 } 23 24 inline Node* new_Node() 25 { 26 Node* now=&t[ne++]; 27 now->s[0]=now->s[1]=&null; 28 now->size=1; 29 return now; 30 } 31 32 inline void _update(Node* now) 33 { 34 now->size=now->s[0]->size+now->s[1]->size+1; 35 } 36 37 inline void _rot(Node* &now,int l) 38 { 39 int r=!l; 40 Node* s=now->s[l]; 41 now->s[l]=s->s[r]; 42 s->s[r]=now; 43 s->size=now->size; 44 _update(now); 45 now=s; 46 } 47 48 void _maintain(Node* &now,int l) 49 { 50 int r=!l; 51 if (now->s[l]->s[l]->size > now->s[r]->size) 52 _rot(now,l); 53 else 54 if (now->s[l]->s[r]->size > now->s[r]->size) 55 { 56 _rot(now->s[l],r); 57 _rot(now,l); 58 } 59 else 60 return; 61 _maintain(now->s[0],0); 62 _maintain(now->s[1],1); 63 _maintain(now,0); 64 _maintain(now,1); 65 } 66 67 void insert(Node* &now,int v) 68 { 69 if (now == &null) 70 { 71 now=new_Node(); 72 now->v=v; 73 return; 74 } 75 now->size++; 76 insert(now->s[v >= now->v],v); 77 _maintain(now,v >= now->v); 78 } 79 80 int del(Node* &now,int v) 81 { 82 now->size--; 83 if ((now->v == v) || (v < now->v && now->s[0] == &null) || (v > now->v && now->s[1] == &null)) 84 { 85 int ans=now->v; 86 if (now->s[0] == &null) 87 now=now->s[1]; 88 else 89 if (now->s[1] == &null) 90 now=now->s[0]; 91 else 92 now->v=del(now->s[1],0); 93 return ans; 94 } 95 else 96 del(now->s[v > now->v],v); 97 } 98 99 inline int get_rank(int v) 100 { 101 Node* now=root; 102 int ans=0; 103 while (1) 104 { 105 if (now == &null) 106 return ans+1; 107 if (now->v < v) 108 { 109 ans+=now->s[0]->size+1; 110 now=now->s[1]; 111 } 112 else 113 now=now->s[0]; 114 } 115 } 116 117 inline int select(int v) 118 { 119 Node* now=root; 120 while (1) 121 { 122 if (now->s[0]->size+1 == v) 123 return now->v; 124 if (v <= now->s[0]->size) 125 now=now->s[0]; 126 else 127 { 128 v-=now->s[0]->size+1; 129 now=now->s[1]; 130 } 131 } 132 } 133 134 inline int pred(int v) 135 { 136 Node* now=root; 137 int ans=0; 138 while (1) 139 { 140 if (now == &null) 141 return ans; 142 if (v <= now->v) 143 now=now->s[0]; 144 else 145 { 146 ans=now->v; 147 now=now->s[1]; 148 } 149 } 150 } 151 152 inline int succ(int v) 153 { 154 Node* now=root; 155 int ans=0; 156 while (1) 157 { 158 if (now == &null) 159 return ans; 160 if (v >= now->v) 161 now=now->s[1]; 162 else 163 { 164 ans=now->v; 165 now=now->s[0]; 166 } 167 } 168 } 169 170 inline bool find(int v) 171 { 172 Node* now=root; 173 while (1) 174 { 175 if (now->v == v) 176 return 1; 177 if (now == &null) 178 return 0; 179 if (v < now->v) 180 now=now->s[0]; 181 else 182 now=now->s[1]; 183 } 184 } 185 186 void travel(Node* now) 187 { 188 if (now->s[0] != &null) 189 travel(now->s[0]); 190 printf("%d ",now->v); 191 if (now->s[1] != &null) 192 travel(now->s[1]); 193 } 194 }t; 195 196 inline void read(int &x) 197 { 198 char ch; 199 bool flag=0; 200 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-')); 201 if (ch == '-') 202 flag=1; 203 else 204 x=ch-'0'; 205 while (ch=getchar(),ch <= '9' && ch >= '0') 206 x=(x<<3)+x+x+ch-'0'; 207 if (flag) 208 x=-x; 209 } 210 211 int main() 212 { 213 int _; 214 read(_); 215 while (_--) 216 { 217 int x=0,y=0; 218 read(x); 219 read(y); 220 if (x == 1) 221 t.insert(t.root,y); 222 if (x == 2) 223 if (t.find(y)) 224 t.del(t.root,y); 225 if (x == 3) 226 printf("%d\n",t.get_rank(y)); 227 if (x == 4) 228 printf("%d\n",t.select(y)); 229 if (x == 5) 230 printf("%d\n",t.pred(y)); 231 if (x == 6) 232 printf("%d\n",t.succ(y)); 233 } 234 return 0; 235 }
bzoj3225
每一层做一次矩形面积并。。。我居然不是最慢的。。。感谢psq神犇帮我垫底
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 3010 7 #define d 1005 8 #define inf 0x3f3f3f3f 9 10 struct Node 11 { 12 int cov,len; 13 }t[maxn<<2]; 14 15 struct line 16 { 17 int x,y1,y2,flag; 18 19 inline bool operator < (const line b) const 20 { 21 return x < b.x; 22 } 23 }a[maxn]; 24 25 inline int min(int a,int b) 26 { 27 return a < b ? a : b; 28 } 29 30 inline int max(int a,int b) 31 { 32 return a > b ? a : b; 33 } 34 35 inline void _update(int rt) 36 { 37 if (!t[rt].cov) 38 t[rt].len=t[rt<<1].len+t[rt<<1|1].len; 39 } 40 41 void build(int l,int r,int rt) 42 { 43 t[rt].cov=t[rt].len=0; 44 if (l+1 == r) 45 return; 46 int mid=(l+r)>>1; 47 build(l,mid,rt<<1); 48 build(mid,r,rt<<1|1); 49 } 50 51 void insert(int l,int r,int rt,int L,int R,int add) 52 { 53 if (l >= L && r <= R) 54 { 55 t[rt].cov+=add; 56 if (!t[rt].cov) 57 { 58 if (l+1 == r) 59 t[rt].len=0; 60 else 61 _update(rt); 62 } 63 if (t[rt].cov) 64 t[rt].len=r-l; 65 return; 66 } 67 int mid=(l+r)>>1; 68 if (L < mid) 69 insert(l,mid,rt<<1,L,R,add); 70 if (R > mid) 71 insert(mid,r,rt<<1|1,L,R,add); 72 _update(rt); 73 } 74 75 int n; 76 int x[maxn],y[maxn],z[maxn],r[maxn],b[maxn]; 77 78 inline int work(int now_z) 79 { 80 build(-d,d,1); 81 int cnt=0; 82 for (int i=1;i<=n;i++) 83 if (z[i]-r[i] <= now_z && z[i]+r[i]-1 >= now_z) 84 { 85 cnt++; 86 a[cnt].x=x[i]-r[i]; 87 a[cnt].y1=y[i]-r[i]; 88 a[cnt].y2=y[i]+r[i]; 89 a[cnt].flag=1; 90 b[cnt]=x[i]-r[i]; 91 cnt++; 92 a[cnt].x=x[i]+r[i]; 93 a[cnt].y1=y[i]-r[i]; 94 a[cnt].y2=y[i]+r[i]; 95 a[cnt].flag=-1; 96 b[cnt]=x[i]+r[i]; 97 } 98 sort(a+1,a+cnt+1); 99 sort(b+1,b+cnt+1); 100 int size=unique(b+1,b+cnt+1)-b-1; 101 int ans=0; 102 for (int i=1,now=1;i<size;i++) 103 { 104 while (a[now].x == b[i] && now <= cnt) 105 { 106 insert(-d,d,1,a[now].y1,a[now].y2,a[now].flag); 107 now++; 108 } 109 ans+=(b[i+1]-b[i])*t[1].len; 110 } 111 return ans; 112 } 113 114 int main() 115 { 116 scanf("%d",&n); 117 int _max=-inf,_min=inf; 118 for (int i=1;i<=n;i++) 119 { 120 scanf("%d%d%d%d",&x[i],&y[i],&z[i],&r[i]); 121 _max=max(_max,z[i]+r[i]-1); 122 _min=min(_min,z[i]-r[i]); 123 } 124 int ans=0; 125 for (int i=_min;i<=_max;i++) 126 ans+=work(i); 127 printf("%d\n",ans); 128 return 0; 129 }
bzoj3226
1858的超级弱化版,注意拆点,蛋疼的不是线段树,而是读入和输出
1 #include <cstdio> 2 3 #define maxn 200010 4 5 struct Node 6 { 7 int lazy; 8 9 inline Node() 10 { 11 lazy=-1; 12 } 13 }t[maxn<<2]; 14 15 inline void _pushdown(int rt) 16 { 17 if (t[rt].lazy == -1) 18 return; 19 if (t[rt].lazy != 2) 20 { 21 t[rt<<1].lazy=t[rt].lazy; 22 t[rt<<1|1].lazy=t[rt].lazy; 23 t[rt].lazy=-1; 24 } 25 else 26 { 27 t[rt<<1].lazy=1-t[rt<<1].lazy; 28 t[rt<<1|1].lazy=1-t[rt<<1|1].lazy; 29 t[rt].lazy=-1; 30 } 31 } 32 33 void insert(int l,int r,int rt,int L,int R,int add) 34 { 35 if (l >= L && r <= R) 36 { 37 if (add == 2) 38 t[rt].lazy=1-t[rt].lazy; 39 else 40 t[rt].lazy=add; 41 return; 42 } 43 _pushdown(rt); 44 int mid=(l+r)>>1; 45 if (L <= mid) 46 insert(l,mid,rt<<1,L,R,add); 47 if (R > mid) 48 insert(mid+1,r,rt<<1|1,L,R,add); 49 } 50 51 bool a[maxn]; 52 53 void travel(int l,int r,int rt) 54 { 55 if (l == r) 56 { 57 if (t[rt].lazy == -1 || t[rt].lazy == 0) 58 a[l]=0; 59 else 60 a[l]=1; 61 return; 62 } 63 _pushdown(rt); 64 int mid=(l+r)>>1; 65 travel(l,mid,rt<<1); 66 travel(mid+1,r,rt<<1|1); 67 } 68 69 int main() 70 { 71 int n=200010; 72 char s[2]; 73 while (~scanf("%s",s)) 74 { 75 int add1=0,add2=0; 76 int x,y; 77 char ch; 78 while (ch=getchar(),ch != '[' && ch != '('); 79 if (ch == '[') 80 add1=1; 81 scanf("%d,%d",&x,&y); 82 x=3*(x+1); 83 y=3*(y+1); 84 x-=add1; 85 while (ch=getchar(),ch != ']' && ch != ')'); 86 if (ch == ']') 87 add2=1; 88 else 89 add2=2; 90 y-=add2; 91 if (x > y) 92 continue; 93 if (s[0] == 'U') 94 insert(1,n,1,x,y,1); 95 if (s[0] == 'I') 96 { 97 insert(1,n,1,1,x-1,0); 98 insert(1,n,1,y+1,n,0); 99 } 100 if (s[0] == 'D') 101 insert(1,n,1,x,y,0); 102 if (s[0] == 'C') 103 { 104 insert(1,n,1,1,x-1,0); 105 insert(1,n,1,y+1,n,0); 106 insert(1,n,1,x,y,2); 107 } 108 if (s[0] == 'S') 109 insert(1,n,1,x,y,2); 110 } 111 travel(1,n,1); 112 int now=0; 113 bool ans=0; 114 for (int i=1;i<=n;i++) 115 if (a[i]) 116 { 117 if (!now) 118 { 119 if (i%3 == 2) 120 putchar('['); 121 else 122 putchar('('); 123 printf("%d,",(i-1)/3); 124 now=1; 125 } 126 else 127 continue; 128 ans=1; 129 } 130 else 131 { 132 if (now) 133 { 134 int p=i-1; 135 printf("%d",(p-1)/3); 136 if (p%3 == 1) 137 putchar(')'); 138 else 139 putchar(']'); 140 putchar(' '); 141 now=0; 142 } 143 else 144 continue; 145 } 146 if (!ans) 147 puts("empty set"); 148 return 0; 149 }
bzoj3231
矩阵快速幂
1 #include <cstdio> 2 #include <cstring> 3 4 long long k,p; 5 6 inline long long inc(long long &a,long long b) 7 { 8 a+=b; 9 while (a >= p) 10 a%=p; 11 } 12 13 inline long long quick_add(long long a,long long b) 14 { 15 long long ans=0; 16 for (;b;b>>=1) 17 { 18 if (b&1) 19 inc(ans,a); 20 inc(a,a); 21 } 22 return ans; 23 } 24 25 struct matrix 26 { 27 long long a[17][17]; 28 29 inline matrix() 30 { 31 memset(a,0,sizeof(a)); 32 } 33 34 inline matrix operator * (const matrix b) const 35 { 36 matrix temp; 37 for (long long i=1;i<=k+1;i++) 38 for (long long j=1;j<=k+1;j++) 39 for (long long l=1;l<=k+1;l++) 40 inc(temp.a[i][j],a[i][l]*b.a[l][j]%p); 41 return temp; 42 } 43 }a,b,ans,wk; 44 45 int main() 46 { 47 scanf("%lld",&k); 48 for (long long i=1;i<=k;i++) 49 scanf("%lld",&b.a[1][i]); 50 for (long long i=1;i<=k;i++) 51 { 52 scanf("%lld",&a.a[k-i+1][k]); 53 a.a[k-i+1][k+1]=a.a[k-i+1][k]; 54 } 55 for (long long i=1;i<k;i++) 56 a.a[i+1][i]=1; 57 a.a[k+1][k+1]=1; 58 long long n,m; 59 long long sum1=0,sum2=0; 60 scanf("%lld%lld%lld",&m,&n,&p); 61 for (long long i=1;i<=k;i++) 62 { 63 b.a[1][i]%=p; 64 inc(b.a[1][k+1],b.a[1][i]); 65 } 66 for (long long i=1;i<=k+1;i++) 67 for (long long j=1;j<=k+1;j++) 68 a.a[i][j]%=p; 69 m--; 70 matrix temp; 71 if (m > k) 72 { 73 ans=b; 74 wk=a; 75 m-=k; 76 long long sum=0; 77 for (;m;m>>=1) 78 { 79 if (m&1) 80 { 81 for (int i=1;i<=k+1;i++) 82 { 83 temp.a[1][i]=0; 84 for (int j=1;j<=k+1;j++) 85 inc(temp.a[1][i],ans.a[1][j]*wk.a[j][i]%p); 86 } 87 for (int i=1;i<=k+1;i++) 88 ans.a[1][i]=temp.a[1][i]; 89 } 90 wk=wk*wk; 91 } 92 sum1=ans.a[1][k+1]; 93 } 94 else 95 for (long long i=1;i<=m;i++) 96 (sum1+=b.a[1][i])%=p; 97 if (n > k) 98 { 99 ans=b; 100 wk=a; 101 n-=k; 102 for (;n;n>>=1) 103 { 104 if (n&1) 105 { 106 for (int i=1;i<=k+1;i++) 107 { 108 temp.a[1][i]=0; 109 for (int j=1;j<=k+1;j++) 110 inc(temp.a[1][i],ans.a[1][j]*wk.a[j][i]%p); 111 } 112 for (int i=1;i<=k+1;i++) 113 ans.a[1][i]=temp.a[1][i]; 114 } 115 wk=wk*wk; 116 } 117 sum2+=ans.a[1][k+1]; 118 } 119 else 120 for (long long i=1;i<=n;i++) 121 (sum2+=b.a[1][i])%=p; 122 long long sum=sum2-sum1; 123 if (sum < 0) 124 sum+=p; 125 printf("%lld\n",sum); 126 return 0; 127 }
bzoj3236
YY出来了一个O(nlog^2n)的做法,可持久化树状数组套主席树,只不过常数有点大,然后写了。。。事实证明复杂度这东西靠不住,O(nsqrt(n)logn)的莫队写得好的快我5倍多我会乱说?
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define maxn 100010 7 8 struct Node 9 { 10 int size; 11 Node *s[2]; 12 }t[40000010],*root[maxn],*time[maxn],null; 13 14 int n; 15 int ne=0; 16 int a[maxn]; 17 int head[maxn],next[maxn]; 18 19 inline void read(int &x) 20 { 21 x=0; 22 char ch; 23 while (ch=getchar(),ch > '9' || ch < '0'); 24 x=ch-'0'; 25 while (ch=getchar(),ch <= '9' && ch >= '0') 26 x=(x<<3)+x+x+ch-'0'; 27 } 28 29 Node* update(Node* pre,int l,int r,int pos) 30 { 31 Node* now=&t[ne++]; 32 now->s[0]=pre->s[0]; 33 now->s[1]=pre->s[1]; 34 now->size=pre->size+1; 35 if (l == r) 36 return now; 37 int mid=(l+r)>>1; 38 if (pos <= mid) 39 now->s[0]=update(pre->s[0],l,mid,pos); 40 else 41 now->s[1]=update(pre->s[1],mid+1,r,pos); 42 return now; 43 } 44 45 inline int query(Node* now,int l,int r,int pos) 46 { 47 int ans=0; 48 while (1) 49 { 50 if (l == r) 51 { 52 ans+=now->size; 53 return ans; 54 } 55 int mid=(l+r)>>1; 56 if (pos <= mid) 57 { 58 now=now->s[0]; 59 r=mid; 60 } 61 else 62 { 63 ans+=now->s[0]->size; 64 now=now->s[1]; 65 l=mid+1; 66 } 67 } 68 } 69 70 Node* bit_update(Node* pre,int l,int r,int pos,int val) 71 { 72 Node* now=&t[ne++]; 73 now->s[0]=pre->s[0]; 74 now->s[1]=pre->s[1]; 75 if (l == r) 76 { 77 now=update(pre,1,n+1,val); 78 return now; 79 } 80 int mid=(l+r)>>1; 81 if (pos <= mid) 82 now->s[0]=bit_update(pre->s[0],l,mid,pos,val); 83 else 84 now->s[1]=bit_update(pre->s[1],mid+1,r,pos,val); 85 return now; 86 } 87 88 inline int query(Node* now,int pos) 89 { 90 int l=1,r=n+1,ans=0; 91 while (1) 92 { 93 if (l == r) 94 { 95 ans+=now->size; 96 return ans; 97 } 98 int mid=(l+r)>>1; 99 if (pos < mid) 100 { 101 ans+=now->s[1]->size; 102 now=now->s[0]; 103 r=mid; 104 } 105 else 106 { 107 now=now->s[1]; 108 l=mid+1; 109 } 110 } 111 } 112 113 inline int bit_query(Node* now,int pos,int val) 114 { 115 int l=1,r=n; 116 while (1) 117 { 118 if (l == r) 119 return query(now,val); 120 int mid=(l+r)>>1; 121 if (pos <= mid) 122 { 123 r=mid; 124 now=now->s[0]; 125 } 126 else 127 { 128 l=mid+1; 129 now=now->s[1]; 130 } 131 } 132 } 133 134 int main() 135 { 136 null.size=0; 137 null.s[0]=null.s[1]=&null; 138 int m; 139 read(n); 140 read(m); 141 for (int i=1;i<=n;i++) 142 read(a[i]); 143 root[0]=&null; 144 for (int i=1;i<=n;i++) 145 root[i]=update(root[i-1],1,n,a[i]); 146 for (int i=1;i<=n;i++) 147 head[i]=n+1; 148 for (int i=n;i;i--) 149 { 150 next[i]=head[a[i]]; 151 head[a[i]]=i; 152 } 153 time[0]=&null; 154 for (int i=1;i<=n;i++) 155 { 156 time[i]=time[i-1]; 157 for (int now=head[i];now!=n+1;now=next[now]) 158 for (int j=now;j<=n;j+=j&-j) 159 time[i]=bit_update(time[i],1,n,j,next[now]); 160 } 161 for (int i=1;i<=m;i++) 162 { 163 int l,r,a,b; 164 read(l); 165 read(r); 166 read(a); 167 read(b); 168 int ans=query(root[r],1,n,b)-query(root[l-1],1,n,b); 169 if (a > 1) 170 ans-=query(root[r],1,n,a-1)-query(root[l-1],1,n,a-1); 171 printf("%d ",ans); 172 ans=0; 173 for (int now=r;now;now-=now&-now) 174 ans+=bit_query(time[b],now,r); 175 for (int now=l-1;now;now-=now&-now) 176 ans-=bit_query(time[b],now,r); 177 if (a > 1) 178 { 179 for (int now=r;now;now-=now&-now) 180 ans-=bit_query(time[a-1],now,r); 181 for (int now=l-1;now;now-=now&-now) 182 ans+=bit_query(time[a-1],now,r); 183 } 184 printf("%d\n",ans); 185 } 186 return 0; 187 }
bzoj3239
baby step giant step
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define maxn 100010 8 9 typedef pair <long long ,long long > pii; 10 11 pii a[maxn]; 12 13 inline long long pow(long long a,long long b,long long p) 14 { 15 long long ans=1; 16 a%=p; 17 while (b) 18 { 19 if (b&1) 20 (ans*=a)%=p; 21 (a*=a)%=p; 22 b>>=1; 23 } 24 return ans; 25 } 26 27 inline bool cmp(const pii a,const pii b) 28 { 29 return (a.first < b.first) || (a.first == b.first && a.second < b.second); 30 } 31 32 int main() 33 { 34 long long b,n,p; 35 while (~scanf("%lld%lld%lld",&p,&b,&n)) 36 { 37 long long m=(int)ceil(sqrt((double)(p-1))); 38 a[0].first=1; 39 a[0].second=0; 40 for (long long i=1;i<m;i++) 41 { 42 a[i].first=(a[i-1].first*b)%p; 43 a[i].second=i; 44 } 45 sort(a,a+m,cmp); 46 long long size=1; 47 for (long long i=1;i<m;i++) 48 if (a[i].first != a[i-1].first) 49 a[size++]=a[i]; 50 long long wk=pow(pow(b,p-2,p),m,p); 51 long long tmp=n; 52 long long ans=-1; 53 for (long long i=0;i<m;i++) 54 { 55 long long now=lower_bound(a+1,a+m,make_pair(tmp,0LL))-a; 56 if (a[now].first == tmp) 57 { 58 ans=a[now].second+i*m; 59 break; 60 } 61 (tmp*=wk)%=p; 62 } 63 if (ans < 0) 64 puts("no solution"); 65 else 66 printf("%lld\n",ans); 67 } 68 return 0; 69 }