蒟蒻的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
",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
",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 }
View Code

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("
");
 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 }
View Code

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
",f[t]);
123     return 0;
124 }
View Code

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("
");
 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 }
View Code

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
",ans);
80     return 0;
81 }
View Code

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 }
View Code

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 }
View Code

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
",now);
105     return 0;
106 }
View Code

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 }
View Code

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
",f[i]);
32     return 0;
33 }
View Code

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
",q[now]);
36             ans=q[now];
37         }
38     }
39     return 0;
40 }
View Code

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
",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 }
View Code

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
",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 }
View Code

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
",ans[i]);
97     return 0;
98 }
View Code

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
",dfs(x,y,n));
32     return 0;
33 }
View Code

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
",calc(b)-calc(a-1));
64     return 0;
65 }
View Code

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
",ans);
    return 0;
}
View Code

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
",ans);
100     return 0;
101 }
View Code

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 }
View Code

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
",2*n-ans);
81     return 0;
82 }
View Code

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
",qmax(&t[x],&t[y]));
206             else
207                 printf("%d
",qsum(&t[x],&t[y]));
208         }
209     }
210     return 0;
211 }
View Code

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
",calc(v));
56     }
57     return 0;
58 }
View Code

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 }
View Code

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
",ans[x]);
100     }
101     return 0;
102 }
View Code

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
",ans);
123     return 0;
124 }
View Code

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
",size[i]);
91             return 0;
92         }
93     return 0;
94 }
View Code

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
",ans);
104     return 0;
105 }
View Code

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
",crf_min);
234         if (s[0] == 'M' && s[4] == 'S')
235             printf("%d
",now_min);
236     }
237     return 0;
238 }
View Code

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 }
View Code

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
",min_cost());
135     return 0;
136 }
View Code

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
",sum-dinic());
135     return 0;
136 }
View Code

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
");
 72             else
 73             {
 74                 int nowv=query(l+1,r-1);
 75                 if (nowv>=z[r].v) printf("false
");
 76                 else
 77                 {
 78                     if (r-l+1==z[r].y-z[l].y+1) printf("true
");
 79                     else printf("maybe
");
 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
");
 91                 else printf("maybe
");
 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
");
101                     else printf("maybe
");
102                 }
103                 else printf("maybe
");
104             }
105         }
106     }
107  
108     return 0;
109 }
View Code

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
",(double)min_cost()/n);
113     return 0;
114 }
View Code

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
",f[1][0]);
45     return 0;
46 }
View Code

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 }
View Code

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
",ans);
56     return 0;
57 }
View Code

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("
");
 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 }
View Code

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
",_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
",ans);
151     return 0;
152 }
View Code

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 }
View Code

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
",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 }
View Code

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-dinic());
135     return 0;
136 }
View Code

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
",b[ans]);
272             else
273                 printf("invalid request!
");
274         }
275     }
276     return 0;
277 }
View Code

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
",spfa());
148     return 0;
149 }
View Code

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
",ans);
110     return 0;
111 }
View Code

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
",upper_bound(bit,bit+40,x)-bit);
16     return 0;
17 }
View Code

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
",ans);
90     return 0;
91 }
View Code

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
",ans+1);
46     return 0;
47 }
View Code

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
",ans);
202     return 0;
203 }
View Code

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
",ans);
36     return 0;
37 }
View Code

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
",min_cost());
127     return 0;
128 }
View Code

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
",query(1,n,1,y,z));
82     }
83     return 0;
84 }
View Code

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
",f[n]);
48     return 0;
49 }
View Code

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
",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
",t.query(y,z));
222     }
223     return 0;
224 }
View Code

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
",ans);
21     return 0;
22 }
View Code

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("
");
242         return(0);
243     }
244     int printl()
245     {
246         if (zf==true) printf("%d
",l);
247         else printf("%d
",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 }
View Code

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
",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
",dinic());
160     return 0;
161 }
View Code

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] == '
' || s[i] == '
')
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("
");
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 != '
' && c != '
')
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 }
View Code

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
",ans);
102 }
View Code

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
",now);
57     return 0;
58 }
View Code

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
",ans);
45     return 0;
46 }
View Code

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
",ans);
51     return 0;
52 }
View Code

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,&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 != '
' && ch != '
');
32         minb=min(minb,now);
33     }
34     for (int i=1;i<=n;i++)
35         ming=min(ming,a[i]);
36     printf("%d
",min(n,min(ming,minb)+k));
37     return 0;
38 }
View Code

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
",ans[i]);
32     return 0;
33 }
View Code

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
",dinic());
122     return 0;
123 }
View Code

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 }
View Code

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
",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 }
View Code

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
",ans);
54     return 0;
55 }
View Code

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
",ans);
95     return 0;
96 }
View Code

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
",sum-dinic());
103     return 0;
104 }
View Code

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
",t.query_sum(pos,len));
293         }
294         if (s[0] == 'M' && s[2] == 'X')
295             printf("%d
",t.query_max());
296     }
297     return 0;
298 }
View Code

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
",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
",t.find(x));
147     }
148     printf("%d
",t.ne-t.root->size);
149     return 0;
150 }
View Code

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] == '
' || s[i] == '
');
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 }
View Code

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 }
View Code

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
",ans);
32     return 0;
33 }
View Code

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
",ans);
73     return 0;
74 }
View Code

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
",f[tx][ty][t]);
38     return 0;
39 }
View Code

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
",f[0]);
53     return 0;
54 }
View Code

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
",query(x,y));
61     }
62     return 0;
63 }
View Code

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
",ans);
17     return 0;
18 }
View Code

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
",f[n][m]);
28     return 0;
29 }
View Code

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
",query(x,y));
61     }
62     return 0;
63 }
View Code

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
",ans);
92     return 0;
93 }
View Code

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
",sec[n]);
94     return 0;
95 }
View Code

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 }
View Code

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
",query(1,n,1,y,z));
121     }
122     return 0;
123 }
View Code

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
",ans*(ans-1)/2);
24     return 0;
25 }
View Code

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
",ans);
53     return 0;
54 }
View Code

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
",sqrt(a[i].dist));
71             return 0;
72         }
73         _union(x,y);
74         cnt--;
75     }
76     return 0;
77 }
View Code

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
",ans);
90     return 0;
91 }
View Code

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
",min_cost());
156     return 0;
157 }
View Code

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
",i-1);
53             break;
54         }
55     }
56     return 0;
57 }
View Code

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
",ans);
65     return 0;
66 }
View Code

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
",query(1,n,1,y,z));
236         if (x == 4)
237             printf("%d
",query_all(1,n,1,y,z));
238     }
239     return 0;
240 }
View Code

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
",t.ask(x));
252         if (ch[0] == 'Q')
253             printf("%d
",t.query(x));
254     }
255     return 0;
256 }
View Code

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))
View Code

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
",flow,ans);
136     return 0;
137 }
View Code

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 }
View Code

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
",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 }
View Code

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 }
View Code

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
",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
",_ans);
118     return 0;
119 }
View Code

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
",min_cost());
129     return 0;
130 }
View Code

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
",dinic());
116     return 0;
117 }
View Code

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
",simplex());
146     return 0;
147 }
View Code

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("
");
 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 }
View Code

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
",sum-dinic());
149     return 0;
150 }
View Code

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 }
View Code

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
",ans);
36     return 0;
37 }
View Code

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
",ans);
42     return 0;
43 }
View Code

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
",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 }
View Code

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 }
View Code

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
",ans);
115     return 0;
116 }
View Code

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
",spfa());
135     return 0;
136 }
View Code

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 }
View Code

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
",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
",ans.first);
125     return 0;
126 }
View Code

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 }
View Code

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 "
",f[1]);
57     return 0;
58 }
View Code

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
",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 }
View Code

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
",ans>>1);
165     return 0;
166 }
View Code

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
",ans);
212     return 0;
213 }
View Code

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
",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
",now_ans);
168     }
169     return 0;
170 }
View Code

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
",ans);
150     }
151     return 0;
152 }
View Code

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
",ans-dinic());
103     return 0;
104 }
View Code

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
",ans);
40     return 0;
41 }
View Code

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
",ans);
67     return 0;
68 }
View Code

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
",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
",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 }
View Code

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
",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
",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
",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 }
View Code

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
",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
",query(&t[x],&t[y]));
235         }
236     }
237     return 0;
238 }
View Code

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
",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);
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 }
View Code

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 }
View Code

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
",ans);
40     return 0;
41 }
View Code

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
",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 }
View Code

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-f[n]);
47     return 0;
48 }
View Code

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
",ans[1][1]);
55     return 0;
56 }
View Code

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
",ans);
90     }
91     else
92         printf("-1
");
93     return 0;
94 }
View Code

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 "
",ans);
68     return 0;
69 }
View Code

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
",ans);
60 }
61 
62 int main()
63 {
64     scanf("%d
",&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 }
View Code

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 }
View Code

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
",min_cost());
127     return 0;
128 }
View Code

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
",ans);
75     printf("%d
",_min+xx);
76     return 0;
77 }
View Code

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
",f[n][k+1]);
25     return 0;
26 }
View Code

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
",ans);
65     return 0;
66 }
View Code

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
",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
",now);
100     }
101     return 0;
102 }
View Code

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
",min(f[cnt][0],f[cnt][1]));
70     return 0;
71 }
View Code

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;
}
View Code

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 }
View Code

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
",spfa(pos[sx][sy],pos[tx][ty]));
115     }
116     return 0;
117 }
View Code

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
",sum,ans);
57     }
58     return 0;
59 }
View Code

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
",ans);
15     }
16     return 0;
17 }
View Code

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 }
View Code

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] == '

相关推荐