成都网络赛
Coder
您找到了这个链接吗http://www.codeforces.com/problemset/problem/85/D
我什么都不想说了。
线段树的题,还要考虑子集合并。
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
//#define ull unsigned __int64
#define ll __int64
//#define ull unsigned long long
//#define ll long long
#define son1 New(p.xl,xm,p.yl,ym),(rt<<2)-2
#define son2 New(p.xl,xm,min(ym+1,p.yr),p.yr),(rt<<2)-1
#define son3 New(min(xm+1,p.xr),p.xr,p.yl,ym),rt<<2
#define son4 New(min(xm+1,p.xr),p.xr,min(ym+1,p.yr),p.yr),rt<<2|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define middle (l+r)>>1
#define esp (1e-8)
const int INF=0x3F3F3F3F;
const double DINF=10000.00;
//const double pi=acos(-1.0);
const int N=100010;
int n,m,tot;
int cnt[N<<2];
ll sum[N<<2][5],X[N];
struct node{
char op[2];
ll x;
void write(){
scanf("%s",op);
if(op[0]!='s') scanf("%I64d",&x),X[m++]=x;
}
}a[N];
int bs(ll key,int size,ll A[]){
int l=0,r=size-1,mid;
while(l<=r){
mid=middle;
if(key>A[mid]) l=mid+1;
else if(key<A[mid]) r=mid-1;
else return mid;
}return -1;
}
void PushUp(int rt){
int i,j,k,ls=rt<<1,rs=ls|1;
for(i=0,j=cnt[ls]%5;i<5;i++){
k=i-j;
sum[rt][i]=sum[ls][i]+sum[rs][k<0? k+5:k];
}
cnt[rt]=cnt[ls]+cnt[rs];
}
void Update(int l,int r,int rt,int p,ll c){
if(l==r){
cnt[rt]= c? 1:0;
sum[rt][1]=c;
return;
}
int mid=middle;
if(p<=mid) Update(lson,p,c);
else Update(rson,p,c);
PushUp(rt);
}
void init(){
int i;
for(i=m=0;i<n;i++) a[i].write();
sort(X,X+m);
for(i=tot=1;i<m;i++) if(X[i]!=X[i-1]) X[tot++]=X[i];
memset(sum,0,sizeof(sum));
memset(cnt,0,sizeof(cnt));
}
void sof(){
for(int i=0,pos;i<n;i++){
if(a[i].op[0]=='s') printf("%I64d\n",sum[1][3]);
else{
pos=bs(a[i].x,tot,X)+1;
if(a[i].op[0]=='a') Update(1,n,1,pos,a[i].x);
else Update(1,n,1,pos,0);
}
}
}
int main(){
while(scanf("%d",&n)!=EOF) init(),sof();
return 0;
}
A Short problem
计算g(g(g(n)))%(1e9+7),这个二阶递推式总会出现循环的,直接开一个1.5G的数组跑出三个循环节,最后答案只有240种可能,本地打表吧。我会说连矩阵快速幂都不用吗(⊙ o ⊙ )!
#include <stdio.h>
long long mod0=240,mod1=183120,mod2=222222224,mod3=1e9+7;
long long cg[240];
void init();
int main()
{
init();
long long n;
while (~scanf("%I64d",&n))
{
n=n%mod0;
printf("%I64d\n",cg[n]);
}
}
void init()
{
cg[0]=0;
cg[1]=1;
cg[2]=42837;
cg[3]=301657676;
cg[4]=293732885;
cg[5]=490640373;
cg[6]=33742025;
cg[7]=164692016;
cg[8]=462308703;
cg[9]=52762375;
cg[10]=343131756;
cg[11]=21405314;
cg[12]=237068195;
cg[13]=596899309;
cg[14]=906139148;
cg[15]=211536041;
cg[16]=366655491;
cg[17]=896628168;
cg[18]=66227266;
cg[19]=72120020;
cg[20]=402845524;
cg[21]=142832152;
cg[22]=798631844;
cg[23]=624391292;
cg[24]=206125778;
cg[25]=943175270;
cg[26]=640019193;
cg[27]=303259648;
cg[28]=182635905;
cg[29]=579125043;
cg[30]=579433543;
cg[31]=83927026;
cg[32]=717557117;
cg[33]=40368430;
cg[34]=863093688;
cg[35]=335922744;
cg[36]=512468934;
cg[37]=813575940;
cg[38]=844062243;
cg[39]=707187631;
cg[40]=278519020;
cg[41]=670147186;
cg[42]=933772741;
cg[43]=378841811;
cg[44]=627788085;
cg[45]=258191260;
cg[46]=844841005;
cg[47]=802471932;
cg[48]=662733064;
cg[49]=781240855;
cg[50]=676645643;
cg[51]=236653810;
cg[52]=511827197;
cg[53]=880889921;
cg[54]=799930429;
cg[55]=42383237;
cg[56]=938628882;
cg[57]=679827669;
cg[58]=909921493;
cg[59]=863143716;
cg[60]=347415371;
cg[61]=427513662;
cg[62]=372282604;
cg[63]=576747399;
cg[64]=938628882;
cg[65]=839037397;
cg[66]=33742025;
cg[67]=420342938;
cg[68]=835920182;
cg[69]=193194645;
cg[70]=57151287;
cg[71]=416852020;
cg[72]=337266943;
cg[73]=547930942;
cg[74]=487542115;
cg[75]=764567815;
cg[76]=676186842;
cg[77]=326357106;
cg[78]=772837852;
cg[79]=284929959;
cg[80]=278519020;
cg[81]=473357016;
cg[82]=682900754;
cg[83]=316947814;
cg[84]=153532664;
cg[85]=804007392;
cg[86]=859774430;
cg[87]=848575784;
cg[88]=717557117;
cg[89]=50843067;
cg[90]=579433543;
cg[91]=857877224;
cg[92]=164332999;
cg[93]=157021226;
cg[94]=414571236;
cg[95]=568476330;
cg[96]=793874229;
cg[97]=136594603;
cg[98]=693461119;
cg[99]=491013304;
cg[100]=138865244;
cg[101]=804171493;
cg[102]=227162155;
cg[103]=610297485;
cg[104]=366655491;
cg[105]=248827358;
cg[106]=293577661;
cg[107]=347255110;
cg[108]=998948656;
cg[109]=859995852;
cg[110]=375475523;
cg[111]=809290428;
cg[112]=462308703;
cg[113]=118039786;
cg[114]=799930429;
cg[115]=339244061;
cg[116]=247992086;
cg[117]=78659144;
cg[118]=503609964;
cg[119]=396857679;
cg[120]=0;
cg[121]=396857679;
cg[122]=503609964;
cg[123]=78659144;
cg[124]=247992086;
cg[125]=339244061;
cg[126]=200069578;
cg[127]=118039786;
cg[128]=462308703;
cg[129]=809290428;
cg[130]=375475523;
cg[131]=859995852;
cg[132]=1051351;
cg[133]=347255110;
cg[134]=293577661;
cg[135]=248827358;
cg[136]=366655491;
cg[137]=610297485;
cg[138]=772837852;
cg[139]=804171493;
cg[140]=138865244;
cg[141]=491013304;
cg[142]=693461119;
cg[143]=136594603;
cg[144]=206125778;
cg[145]=568476330;
cg[146]=414571236;
cg[147]=157021226;
cg[148]=164332999;
cg[149]=857877224;
cg[150]=420566464;
cg[151]=50843067;
cg[152]=717557117;
cg[153]=848575784;
cg[154]=859774430;
cg[155]=804007392;
cg[156]=846467343;
cg[157]=316947814;
cg[158]=682900754;
cg[159]=473357016;
cg[160]=278519020;
cg[161]=284929959;
cg[162]=227162155;
cg[163]=326357106;
cg[164]=676186842;
cg[165]=764567815;
cg[166]=487542115;
cg[167]=547930942;
cg[168]=662733064;
cg[169]=416852020;
cg[170]=57151287;
cg[171]=193194645;
cg[172]=835920182;
cg[173]=420342938;
cg[174]=966257982;
cg[175]=839037397;
cg[176]=938628882;
cg[177]=576747399;
cg[178]=372282604;
cg[179]=427513662;
cg[180]=652584636;
cg[181]=863143716;
cg[182]=909921493;
cg[183]=679827669;
cg[184]=938628882;
cg[185]=42383237;
cg[186]=200069578;
cg[187]=880889921;
cg[188]=511827197;
cg[189]=236653810;
cg[190]=676645643;
cg[191]=781240855;
cg[192]=337266943;
cg[193]=802471932;
cg[194]=844841005;
cg[195]=258191260;
cg[196]=627788085;
cg[197]=378841811;
cg[198]=66227266;
cg[199]=670147186;
cg[200]=278519020;
cg[201]=707187631;
cg[202]=844062243;
cg[203]=813575940;
cg[204]=487531073;
cg[205]=335922744;
cg[206]=863093688;
cg[207]=40368430;
cg[208]=717557117;
cg[209]=83927026;
cg[210]=420566464;
cg[211]=579125043;
cg[212]=182635905;
cg[213]=303259648;
cg[214]=640019193;
cg[215]=943175270;
cg[216]=793874229;
cg[217]=624391292;
cg[218]=798631844;
cg[219]=142832152;
cg[220]=402845524;
cg[221]=72120020;
cg[222]=933772741;
cg[223]=896628168;
cg[224]=366655491;
cg[225]=211536041;
cg[226]=906139148;
cg[227]=596899309;
cg[228]=762931812;
cg[229]=21405314;
cg[230]=343131756;
cg[231]=52762375;
cg[232]=462308703;
cg[233]=164692016;
cg[234]=966257982;
cg[235]=490640373;
cg[236]=293732885;
cg[237]=301657676;
cg[238]=42837;
cg[239]=1;
}
Food
亲,你找到usaco的题目链接了吗?或者你收藏了《最大流算法及其应用》(南京外国语,贾志鹏)吗?(*^__^*)嘻嘻……节操何在?
这题很好过,用约束条件建图,求最大流,AC。(是不是抄代码更快啊⊙﹏⊙?)看过论文的同学都是直接秒的吧?
/*==================================================*\
| Dinic最大流 O(V^2 * E)
| INIT: ne=2; head[]置为0; addedge()加入所有弧;
| CALL: flow(n, s, t);
\*==================================================*/
#include <cstdio>
#include <string.h>
const int N = 910;
const int E=N*N;
#define typec int // type of cost
const typec inf = 0x3f3f3f3f; // max of cost
struct edge { int x, y, nxt; typec c; } bf[E];
int ne, head[N], cur[N], ps[N], dep[N];
void addedge(int x, int y, typec c)
{ // add an arc(x -> y, c); vertex: 0 ~ n-1;
bf[ne].x = x; bf[ne].y = y; bf[ne].c = c;
bf[ne].nxt = head[x]; head[x] = ne++;
bf[ne].x = y; bf[ne].y = x; bf[ne].c = 0;
bf[ne].nxt = head[y]; head[y] = ne++;
}
typec flow(int n, int s, int t)
{
typec tr, res = 0;
int i, j, k, f, r, top;
while (1) {
memset(dep, -1, n * sizeof(int));
for (f = dep[ps[0] = s] = 0, r = 1; f != r; )
for (i = ps[f++], j = head[i]; j; j = bf[j].nxt)
{
if (bf[j].c && -1 == dep[k = bf[j].y]){
dep[k] = dep[i] + 1; ps[r++] = k;
if (k == t) { f = r; break; }
}
}
if (-1 == dep[t]) break;
memcpy(cur, head, n * sizeof(int));
for (i = s, top = 0; ; ) {
if (i == t) {
for (k = 0, tr = inf; k < top; ++k)
if (bf[ps[k]].c < tr)
tr = bf[ps[f = k]].c;
for (k = 0; k < top; ++k)
bf[ps[k]].c -= tr, bf[ps[k]^1].c += tr;
res += tr; i = bf[ps[top = f]].x;
}
for (j=cur[i]; cur[i]; j = cur[i] = bf[cur[i]].nxt)
if (bf[j].c && dep[i]+1 == dep[bf[j].y]) break;
if (cur[i]) {
ps[top++] = cur[i];
i = bf[cur[i]].y;
}
else {
if (0 == top) break;
dep[i] = -1; i = bf[ps[--top]].x;
}
}
}
return res;
}
int main()
{
int i, j, t, n, f, d;
char s[700];
while ( ~scanf("%d %d %d", &n, &f, &d) )
{
ne=2;
memset(head,0,sizeof(head));
for (i=1; i<=f; i++)
{
scanf("%d",&t);
addedge(0,i,t);
}
for (i=f+1; i<=f+d; i++)
{
scanf("%d",&t);
addedge(i,f+d+n+1+n,t);
}
for (i=1; i<=n; i++)
{
scanf("%s",s+1);
for (j=1; j<=f; j++)
if (s[j]=='Y') addedge(j,f+d+i,1);
}
for (i=1; i<=n; i++) addedge(f+d+i,f+d+n+i,1);
for (i=1; i<=n; i++)
{
scanf("%s",s+1);
for (j=1; j<=d; j++)
if (s[j]=='Y') addedge(f+d+i+n,f+j,1);
}
printf("%d\n",flow(f+d+n+n+2,0,f+d+n+n+1));
}
return 0;
}
Groups
每个人申明了一个区间,某个区间可能被多个人申明。求最多多少人说真话。
问题在于求这些区间合并起来不会相交。区间的权值就是申明该区间的人数(不能大于实际区间长度)。
把这些区间连起来,[a,b]->[c,d]合法当且仅当c>b。这样就有了一个拓扑关系。按照这个拓扑关系状态转移,dp求解。
算法时间复杂度O(n^2)。
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
typedef pair < int, int > pp;
map < pp, int > s;
map < pp, int >::iterator it,p;
int n;
int main(){
int i,a,b,max,tmp;
while ( ~scanf("%d",&n) ){
//init
s.clear();
for (i=0; i<n; i++){
scanf("%d %d", &a, &b);
a++, b=n-b;
if (a>b) continue;
s[pp(a,b)]++;
if ( s[pp(a,b)]>(b-a+1) ) s[pp(a,b)]=(b-a+1);
}
max=0;
for (it=s.begin(); it!=s.end(); it++)
{
tmp=it->second;
for (p=s.begin(); p!=s.end(); p++){
if ( it->first.first > p->first.second ){
if (p->second+tmp>it->second)
it->second=p->second+tmp;
}
}
if (max<it->second) max=it->second;
}
printf("%d\n",max);
}
return 0;
}