2012成都网络赛


成都网络赛

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


 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值