7.3~7.15eg刷题记录

今天是2017/7/10,DCDCBigBig的第二十四篇博文

额,考完期末考结束周之前家里突发急事,赶回安徽,然后又接到集训的通知,结果回来路上发烧40°C+航班取消两次,要死要活地赶到eg。。。(然而期末考还是不(ling)出(ren)意(xin)外(xi)的炸了)

新题库小视野好评~
ps:文内题目持续做&&更新

算法复习

1.KMP

已做

1.【xsy2336】【CF471D】MUH and Cube Walls
KMP+乱搞差值

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int l1,l2,ans=0,s1[200001],s2[200001],nxt[200001];
void kmp(){
    nxt[0]=-1;
    for(int i=1,j=0;i<l1;i++){
        for(j=nxt[i-1];j!=-1&&s1[i]!=s1[j+1];j=nxt[j]);
        if(s1[i]==s1[j+1])j++;
        nxt[i]=j;
    }
    for(int i=0,j=-1;i<l2;i++){
        for(;j!=-1&&s2[i]!=s1[j+1];j=nxt[j]);
        if(s1[j+1]==s2[i])j++;
        if(j==l1-1){
            ans++;
        }
    }
}
int main(){
    scanf("%d%d",&l2,&l1);
    for(int i=0;i<l2;i++){
        scanf("%d",&s2[i]);
    }
    for(int i=0;i<l1;i++){
        scanf("%d",&s1[i]);
    }
    if(l1==1){
        printf("%d",l2);
        return 0;   
    }
    l1--;
    l2--;
    for(int i=0;i<l1;i++){
        s1[i]=s1[i+1]-s1[i];
    }
    for(int i=0;i<l2;i++){
        s2[i]=s2[i+1]-s2[i];
    }
    kmp();
    printf("%d",ans);
    return 0;
}

2.【xsy2338】【bzoj1355】Radio Transmission
(并不是KMP)fail数组应用

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,ans,nxt[1000001];
char s[1000001];
int main(){
    scanf("%d%s",&n,s);
    nxt[0]=-1;
    for(int i=1,j=0;i<n;i++){
        for(j=nxt[i-1];j!=-1&&s[i]!=s[j+1];j=nxt[j]);
        if(s[i]==s[j+1])j++;
        nxt[i]=j;
    }
    ans=n-1;
    while(nxt[ans])ans--;
    printf("%d",ans);
    return 0;
}

3.【xsy2349】【bzoj1355】[Baltic2009]Bazinga
(也不是KMP)strstr大法好

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
char st[2001][2001];
bool check[2001];
int n,T,ans;
int main(){
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        memset(check,0,sizeof(check));
        ans=-1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",st[i]);
            for(int j=i-1;j>=1;j--){
                if(check[j])continue;
                else if(strstr(st[i],st[j])==NULL){
                    ans=i;
                    break;
                }
                else check[j]=true;
            }
        }
        printf("Case #%d: %d\n",t,ans);
    }
    return 0;
}

将做

1.【xsy2335】【NOI2014】动物园
2.【xsy2337】【CF494B】Obsessive String

2.trie

已做

1.【xsy2339】[Balkan2007]Toponyms
trie+dfs

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
struct t_node{
    int nxt;
    char data;
}trie[12000001];
int n,tot=0,head[12000001],anss[12000001];
ll ans;
char st[10000001];
void ins(char st[]){
    int now=0,len=strlen(st);
    for(int i=0;i<len;i++){
        int tmp;
        for(tmp=head[now];trie[tmp].data!=st[i]&&tmp!=-1;tmp=trie[tmp].nxt);
        if(tmp==-1){
            trie[tmp=++tot].data=st[i];
            trie[tmp].nxt=head[now];
            head[now]=tmp;
        }
        now=tmp;
        anss[now]++;
        ans=max(ans,(ll)(i+1)*anss[now]);
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d\n",&n);
    for(int i=1;i<=n;i++){
        gets(st);
        ins(st);
    }
    printf("%lld",ans);
    return 0;
}

2.【xsy2340】【POJ3764】The xor-longest Path
trie+xor

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int v,w,next;
}a[400001];
int n,u,v,w,ans=0,tot=0,tot1=0,num[400001],head[400001],trie[2][4000001];
bool check[400001];
void add(int u,int v,int w){
    a[++tot].v=v;
    a[tot].w=w;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u,int x){
    num[u]=x;
    check[u]=true;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        if(!check[a[tmp].v])dfs(a[tmp].v,a[tmp].w^x);
    }
}
void ins(int x){
    int now=0;
    bool f;
    for(int i=30;i>=0;i--){
        f=x&(1<<i);
        if(trie[f][now])now=trie[f][now];
        else{
            trie[f][now]=++tot1;
            now=tot1;
        } 
    }
}
int query(int x){
    int maxn=0,now=0;
    bool f;
    for(int i=30;i>=0;i--){
        f=x&(1<<i);
        if(trie[!f][now]){
            now=trie[!f][now];
            maxn+=(1<<i);
        }else now=trie[f][now];
    }
    return maxn;
}
int main(){
    memset(head,-1,sizeof(head));
    memset(check,0,sizeof(check));
    memset(trie,0,sizeof(trie));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    dfs(1,0);
    ins(num[1]);
    for(int i=2;i<=n;i++){
        ans=max(ans,query(num[i]));
        ins(num[i]);
    }
    printf("%d",ans);
    return 0;
}

3.【xsy2342】【bzoj4260】REBXOR
trie+xor

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,ans,tot=0,now=0,s[4000001],lf[4000001],rt[4000001],trie[2][10000001];
void add(int x){
    int now=0;
    bool f;
    for(int i=1<<30;i>0;i/=2){
        f=i&x;
        if(trie[f][now])now=trie[f][now];
        else{
            trie[f][now]=++tot;
            now=tot;
        }
    }
}
int query(int x){
    int now=0,ans=0;
    bool f;
    for(int i=1<<30;i>0;i/=2){
        f=!(i&x);
        if(trie[f][now]){
            ans+=i;
            now=trie[f][now];
        }else now=trie[!f][now];
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&s[i]);
    }
    add(0);
    for(int i=1;i<=n;i++){
        now^=s[i];
        add(now);
        lf[i]=max(lf[i-1],query(now));
    }
    memset(trie,0,sizeof(trie));
    now=tot=0;
    add(0);
    for(int i=n;i>=1;i--){
        now^=s[i];
        add(now);
        rt[i]=max(rt[i+1],query(now));
    }
    for(int i=0;i<=n;i++){
        ans=max(ans,lf[i]+rt[i+1]);
    }
    printf("%d",ans);
    return 0;
}

将做

1.【xsy2341】异或之
2.【xsy2343】【SCOI2016】背单词

线段树

已做

1.【xsy2436】[CF487B]Strip
然而并不是线段树

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,s,l,ans=1,maxn,minn,a[100001];
int main(){
    scanf("%d%d%d",&n,&s,&l);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    minn=maxn=a[1];
    for(int i=2;i<=n;i++){
        if(abs(minn-a[i])>s||abs(maxn-a[i])>s){
            maxn=minn=a[i];
            ans++;
        }else{
            maxn=max(maxn,a[i]);
            minn=min(minn,a[i]);
        }
    }
    if(ans*l<=n)printf("%d",ans);
    else printf("-1");
    return 0;
}

2.【xsy2437】[CF373C]计算袋鼠是愉快的
然而也不是线段树

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,ans=0,a[500001];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    sort(a+1,a+n+1);
    ans=n;
    for(int i=n/2;i>0;i--){
        if(a[ans]>=a[i]*2)ans--;
    }
    printf("%d",ans);
    return 0;
} 

将做

太多了不写了

新算法

扩展KMP

已做

0.模板。。。
1.【xsy2346】Prefixes and Suffixes

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int l2,tot=0,nxt[100001],ans[100001];
bool check[100001];
char t[100001];
void getnext(){
    int a=0,p;
    nxt[0]=l2;
    for(int i=1,j=-1;i<l2;i++,j--){
        if(j<0||i+nxt[i-a]>=p){
            if(j<0){
                p=i;
                j=0;
            }
            while(p<l2&&t[p]==t[j]){
                p++;
                j++;
            }
            nxt[i]=j;
            a=i;
        }else nxt[i]=nxt[i-a];
    }
}
int main(){
    memset(nxt,0,sizeof(nxt));
    memset(ans,0,sizeof(ans));
    memset(check,0,sizeof(check));
    scanf("%s",t);
    l2=strlen(t);
    getnext();
    for(int i=0;i<l2;i++){
        if(i+nxt[i]==l2){
            check[nxt[i]]=true;
            tot++;
        }
        ans[nxt[i]]++;
    }
    for(int i=l2-1;i>=1;i--){
        ans[i]+=ans[i+1];
    }
    printf("%d\n",tot);
    for(int i=1;i<=l2;i++){
        if(check[i])printf("%d %d\n",i,ans[i]);
    }
    return 0;
}

2.【xsy2347】Tavas and Malekas

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define modHA 1000000007
using namespace std;
int n,m,tot,s[1000001],nxt[1000001],l2;
long long ans=1;
char t[1000001];
void getnext(){
    int a=0,p;
    nxt[0]=l2;
    for(int i=1,j=-1;i<l2;i++,j--){
        if(j<0||i+nxt[i-a]>=p){
            if(j<0){
                p=i;
                j=0;
            }
            while(p<l2&&t[p]==t[j]){
                p++;
                j++;
            }
            nxt[i]=j;
            a=i;
        }else nxt[i]=nxt[i-a];
    }
}
int main(){
    scanf("%d%d",&n,&m);
    if(m==0){
        for(int i=1;i<=n;i++)ans=(ans*26)%modHA;
        printf("%lld",ans);
        return 0;
    }
    scanf("%s",t);
    l2=strlen(t);
    for(int i=1;i<=m;i++){
        scanf("%d",&s[i]);
    }
    getnext();
    for(int i=1;i<m;i++){
        if(s[i]+l2<s[i+1])continue;
        if(nxt[s[i+1]-s[i]]!=l2-s[i+1]+s[i]){
            printf("0");
            return 0;
        }
    }
    tot=s[1]-1;
    for(int i=1;i<m;i++){
        if(s[i]+l2<s[i+1])tot+=s[i+1]-s[i]-l2;
    }
    if(s[m]+l2-1<n)tot+=n-s[m]-l2+1;
    for(int i=1;i<=tot;i++)ans=(ans*26)%modHA;
    printf("%lld",ans);
    return 0;
}

将做

1.【xsy2348】Revolving Digits

manacher

已做

0.模板。。。
1.【xsy2356】最长回文
就是模板啊。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
char s[100001];
int manacher(char s[]){
    int maxn=0,p[200001],mx=0,id=0,len=strlen(s);
    char st[200001];
    st[0]='$';
    for(int i=0;i<len;i++){
        st[i*2+1]='#';
        st[(i+1)*2]=s[i];
    }
    st[len*2+1]='#';
    for(int i=0;i<2*len;i++){
        if(i<mx)p[i]=min(p[id*2-i],mx-i);
        else p[i]=1;
        while(st[i-p[i]]==st[i+p[i]])p[i]++;
        if(i+p[i]>mx){
            mx=i+p[i];
            id=i;
        }
        maxn=max(maxn,p[i]-1);
    }
    return maxn;
}
int main(){
    while(scanf("%s",s)!=EOF)
    printf("%d\n",manacher(s));
    return 0;
}

2.【xsy2357】吉哥系列故事——完美队形II
还是模板啊。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int t,n,a[100001];
int m(int len){
    int p[200001],st[200001],mx=0,id=0,maxn=0;
    memset(p,0,sizeof(p));
    st[0]=-2;
    for(int i=1;i<=len;i++){
        st[i*2-1]=-1;
        st[i*2]=a[i];
    }
    st[len*2+1]=-1;
    for(int i=1;i<=len*2+1;i++){
        if(i<mx)p[i]=min(mx-i,p[id*2-i]);
        else p[i]=1;
        while(st[i+p[i]]==st[i-p[i]]&&st[i-p[i]]<=st[i-p[i]+2])p[i]++;
        if(i+p[i]>mx){
            mx=i+p[i];
            id=i;
        }
        maxn=max(maxn,p[i]-1);
    }
    return maxn;
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        printf("%d\n",m(n));
    }
    return 0;
}

3.【xsy2359】[POI2010] Antisymmetry

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n;
char s[500001];
long long manacher(){
    int p[2000001],mx=0,id=0,st[2000001],len=n;
    long long maxn=0;
    st[0]=-1;
    for(int i=1;i<=len;i++){
        st[i*2-1]=s[i]-'0';
        st[i*2]=138;
    }
    len=len*2-1;
    //st[len]=138;
    for(int i=2;i<=len;i+=2){
        if(i<mx)p[i]=min(p[id*2-i],mx-i);
        else p[i]=1;
        while(i+p[i]<=len&&i-p[i]>0&&(st[i-p[i]]!=st[i+p[i]]||st[i-p[i]]==138))p[i]++;
        if(i+p[i]>mx){
            mx=i+p[i];
            id=i;
        }
        maxn+=p[i]>>1;
    }
    return maxn;
}
int main(){
    scanf("%d%s",&n,s+1);
    printf("%lld",manacher());
    return 0;
}

将做

1.【xsy2358】Interestring
2.【xsy2360】[CF17E] Palisection

数位DP

已做

1.【xsy1998】Xorequ

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define modHA 1000000007LL
using namespace std;
typedef long long ll;
struct sq{
    ll s[3][3];
    void init(){
        memset(s,0,sizeof(s));
        s[0][0]=s[0][1]=s[1][0]=1;
    }
};
ll t,n,num[101],f[2][101];
ll _cal(int x,int y,bool ch){
    ll ans=0,ss=ch?num[x]:1;
    if(x==0)return 1;
    if(!ch&&f[y][x]!=-1)return f[y][x];
    for(int i=0;i<=ss;i++){
        if(i==0||y==0){
            ans+=_cal(x-1,i,ch&&(i==ss));
        }
    }
    if(!ch){
        f[y][x]=ans;
    }
    return ans;
}
ll cal(ll s){
    int len=0;
    while(s){
        num[++len]=s&1;
        s>>=1;
    }
    return _cal(len,0,true);
}
sq _mul(sq a,sq b){
    sq c;
    memset(c.s,0,sizeof(c.s));
    for(int i=0;i<=1;i++){
        for(int j=0;j<=1;j++){
            for(int k=0;k<=1;k++){
                c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j])%modHA;
            }
        }
    }
    return c;
}
sq fast_pow(sq a,ll s){
    sq tmp;
    memset(tmp.s,0,sizeof(tmp.s));
    tmp.s[0][0]=tmp.s[1][1]=1;
    for(;s;s/=2){
        if(s&1)tmp=_mul(tmp,a);
        a=_mul(a,a);
    }
    return tmp;
}
ll squ_mul(){
    sq a,b;
    a.init();
    memset(b.s,0,sizeof(b.s));
    b.s[0][0]=1;
    a=fast_pow(a,n+1);
    a=_mul(a,b);
    return a.s[0][0];
}
int main(){
    scanf("%lld",&t);
    while(t--){
        memset(f,-1,sizeof(f));
        scanf("%lld",&n);
        printf("%lld\n%lld\n",cal(n)-1,squ_mul());
    }
    return 0;
}

2.【xsy1999】[ZJOI2010] 数字计数

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll a,b,c=1,ans[10],f[13];
void cal(ll s,int ch){
    ll tmp=1,k=10,tt,sum;
    for(;k<s;tmp++,k*=10){
        for(int j=0;j<=9;j++)ans[j]+=f[tmp-1]*9*ch;
        for(int j=1;j<=9;j++)ans[j]+=k/10*ch;
    }
    k/=10;
    tt=k;
    tmp--;
    while(tt<s){
        while(tt+k<=s){
            sum=tt/k;
            while(sum){
                ans[sum%10]+=k*ch;
                sum/=10;
            }
            for(int j=0;j<=9;j++){
                ans[j]+=f[tmp]*ch;
            }
            tt+=k; 
        }
        k/=10;
        tmp--;
    }
}
int main(){
    memset(ans,0,sizeof(ans));
    scanf("%lld%lld",&a,&b);
    f[1]=1;
    for(int i=2;i<=12;i++){
        f[i]=f[i-1]*10+(c=c*10);
    }
    cal(b+1,1);
    cal(a,-1);
    for(int i=0;i<=9;i++){
        printf("%lld ",ans[i]);
    }
    return 0;
}

3.【xsy2000】[SCOI2009] windy数

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll a,b,tot=0LL,f[101][101],num[12];
ll cal(ll s){
    memset(num,0,sizeof(num));
    if(s==0)return 0;
    ll ans=0LL;
    tot=0LL;
    while(s){
        num[++tot]=s%10;
        s/=10;
    }
    for(int i=1;i<num[tot];i++){
        ans+=f[tot][i];
    }
    for(int i=tot-1;i>0;i--){
        for(int j=1;j<=9;j++){
            ans+=f[i][j];
        }
    }
    for(int i=tot-1;i>0;i--){
        for(int j=0;j<num[i];j++){
            if(abs(num[i+1]-j)>=2){
                ans+=f[i][j];
            }
        }
        if(abs(num[i+1]-num[i])<2)break;
    }
    return ans;
}
int main(){
    memset(f,0,sizeof(f));
    scanf("%lld%lld",&a,&b);
    for(int i=0;i<=9;i++){
        f[1][i]=1;
    }
    for(int i=2;i<=10;i++){
        for(int j=0;j<=9;j++){
            for(int k=0;k<=9;k++){
                if(abs(j-k)>=2){
                    f[i][j]+=f[i-1][k];
                }
            }
        }
    }
    printf("%lld",cal(b+1)-cal(a));
    return 0;
}

4.【xsy2001】[POJ3208] Apocalypse Someday

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int w[4][10]={{0,0,0,0,0,0,0,0,0,0},{3,3,3,3,3,3,0,3,3,3},{3,3,3,3,3,3,1,3,3,3},{3,3,3,3,3,3,2,3,3,3}};
ll n,t,tot,sum,f[201][4];
int main(){
    scanf("%d",&t);
    f[0][0]=1;
    for(int i=1;i<=12;i++){
        f[i][0]=(f[i-1][0]+f[i-1][1]+f[i-1][2])*9;
        f[i][1]=f[i-1][0];
        f[i][2]=f[i-1][1];
        f[i][3]=f[i-1][2]+f[i-1][3]*10;
    }
    while(t--){
        tot=0;
        sum=3;
        scanf("%d",&n);
        while(f[tot][3]<n)tot++;
        while(tot){
            ll s=0,now;
            for(int i=0;i<=9;i++){
                now=0;
                for(int j=3;j>=w[sum][i];j--){
                    now+=f[tot-1][j];
                }
                if(s+now>=n){
                    printf("%d",i);
                    sum=w[sum][i];
                    break;
                }
                s+=now;
            }
            n-=s;
            tot--;
        }
        printf("\n");
    }
    return 0;
}

将做

太多了不写了

概率与期望DP

已做

1.【xsy1961】[NOIP2016] 换教室
就这题调了我3h。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,v,e,u,vv,w,c[2001],d[2001],sp[2001][2001];
double k[2000001],f[2001][2001][2],tt,ans;
int main(){
    memset(sp,0x3f,sizeof(sp));
    scanf("%d%d%d%d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&d[i]);
    }
    for(int i=1;i<=n;i++){
        scanf("%lf",&k[i]);
    }
    for(int i=0;i<=v;i++){
        sp[i][i]=0;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            f[i][j][0]=1e16;
            f[i][j][1]=1e16;
        }
    } 
    f[1][0][0]=f[1][1][1]=0;
    for(int i=1;i<=e;i++){
        scanf("%d%d%d",&u,&vv,&w);
        if(u==vv){
            continue;
        }
        sp[u][vv]=min(sp[u][vv],w);
        sp[vv][u]=sp[u][vv];
    }
    for(int kk=1;kk<=v;kk++){
        for(int i=1;i<=v;i++){
            for(int j=1;j<=v;j++){
                sp[i][j]=min(sp[i][kk]+sp[kk][j],sp[i][j]);
            }
        }
    }
    for(int i=2;i<=n;i++){
        f[i][0][0]=f[i-1][0][0]+sp[c[i-1]][c[i]];
        for(int j=1;j<=min(m,i);j++){            
            f[i][j][0]=min(f[i-1][j][0]+sp[c[i-1]][c[i]],f[i-1][j][1]+sp[c[i-1]][c[i]]*(1.0-k[i-1])+sp[d[i-1]][c[i]]*k[i-1]);
            f[i][j][1]=f[i-1][j-1][0]+sp[c[i-1]][c[i]]*(1.0-k[i])+sp[c[i-1]][d[i]]*k[i];
            tt=f[i-1][j-1][1]+sp[c[i-1]][c[i]]*(1.0-k[i-1])*(1.0-k[i])+sp[d[i-1]][c[i]]*k[i-1]*(1.0-k[i])+sp[c[i-1]][d[i]]*(1.0-k[i-1])*k[i]+sp[d[i-1]][d[i]]*k[i-1]*k[i];
            f[i][j][1]=min(f[i][j][1],tt); 
        }
    }
    ans=f[n][0][0];
    for(int i=1;i<=m;i++){
        ans=min(ans,min(f[n][i][1],f[n][i][0]));
    }
    printf("%.2lf",ans);
    return 0;
}

2.【xsy1962】OSU!

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n;
double s,f1[100001],f2[100001],f3[100001];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lf",&s);
        f1[i]=(f1[i-1]+1)*s;
        f2[i]=(f2[i-1]+f1[i-1]*2+1)*s;
        f3[i]=f3[i-1]+(3*(f1[i-1]+f2[i-1])+1)*s;
    }
    printf("%.1lf",f3[n]);
    return 0;
}

3.【xsy1963】概率充电器

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int v,next;
    double w;
}a[1000001];
int n,u,v,w,tot=0,head[1000001];
double ans=0,f[500001],s[500001];
void add(int u,int v,double w){
    a[++tot].v=v;
    a[tot].w=w;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u,int fa){
    int v;
    double w;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        v=a[tmp].v;
        w=a[tmp].w;
        if(v!=fa){
            s[u]=s[u]+s[v]*w-s[u]*s[v]*w;
            dfs(v,u);
        }
    }
}
void dp(int u,int fa){
    int v;
    double w,a1,a2;
    ans+=f[u];
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        v=a[tmp].v;
        w=a[tmp].w;
        if(v!=fa){
            a1=(double)1.0-s[v]*w;
            if(fabs((double)a1-0)<1e-6)f[v]=1.0;
            else{
                a2=(double)(f[u]-s[v]*w)/a1;
                f[v]=s[v]+a2*w-s[v]*a2*w;
            }
            dp(v,u);
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,(double)w/100);
        add(v,u,(double)w/100);
    }
    for(int i=1;i<=n;i++){
        scanf("%lf",&s[i]);
        s[i]=(double)s[i]/100;
    }
    dfs(1,0);
    f[1]=s[1];
    dp(1,0);
    printf("%.6lf",ans);
    return 0;
} 

4.【xsy1964】守卫者的挑战

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct dclyz{
    int a;
    double p;
}a[201];
int n,m,l,s;
double ans=0,f[201][201][201];
bool cmp(dclyz a,dclyz b){
    return a.a>b.a;
}
int main(){
    scanf("%d%d%d",&n,&l,&m);
    for(int i=1;i<=n;i++){
        scanf("%lf",&a[i].p);
        a[i].p=(double)a[i].p/(double)100;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].a);
    }
    sort(a+1,a+n+1,cmp);
    f[0][0][min(n,m)]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            for(int k=0;k<=n;k++){
                f[i][j-1][k]+=f[i-1][j-1][k]*(1-a[i].p);
                if((s=k+a[i].a)<0)continue;
                s=min(s,n);
                f[i][j][s]+=f[i-1][j-1][k]*a[i].p;
            }
        }
    }
    for(int i=l;i<=n;i++){
        for(int j=0;j<=n;j++){
            ans+=f[n][i][j];
        }
    }
    printf("%.6lf",ans);
    return 0;
}

将做

太多了不写了

树形DP

已做

1.【xsy2408】[CF337D]邪恶古籍

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int v,next;
}a[500001];
int n,m,d,u,v,tot=0,ans=0,head[100001],f1[100001],f2[100001];
void add(int u,int v){
    a[++tot].v=v;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u,int fa){
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa){
            dfs(v,u);
            if(f1[v]!=-1){
                f1[u]=max(f1[u],f1[v]+1);
            }
        }
    }
}
void dfs_(int u,int fa){
    int a1=-1,a2=-1;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa){
            if(f2[u]!=-1){
                f2[v]=max(f2[v],f2[u]+1);
            }
            if(f1[v]!=-1){
                if(f1[v]>a1){
                    a2=a1;
                    a1=f1[v];
                }else if(f1[v]>a2){
                    a2=f1[v];
                }
            }
        }
    }
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa){
            if(a1!=-1&&a2!=-1&&f1[v]==a1){
                f2[v]=max(f2[v],a2+2);
            }
            if(f1[v]<a1){
                f2[v]=max(f2[v],a1+2);
            }
            dfs_(v,u);
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    memset(f1,-1,sizeof(f1));
    memset(f2,-1,sizeof(f2));
    scanf("%d%d%d",&n,&m,&d);
    for(int i=1;i<=m;i++){
        scanf("%d",&u);
        f1[u]=f2[u]=0;
    }
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs(1,0);
    dfs_(1,0);
    for(int i=1;i<=n;i++){
        if(max(f1[i],f2[i])<=d)ans++;
    }
    printf("%d",ans);
    return 0;
}

2.【xsy2409】[CF697D]Puzzles

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int v,next;
}a[500001];
int n,u,tot=0,s[100001],head[100001];
double f[100001];
void add(int u,int v){
    a[++tot].v=v;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u){
    s[u]=1;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        dfs(v);
        s[u]+=s[v];
    }
}
void dfs_(int u){
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        f[v]=(double)((double)(s[u]-s[v]-1)*0.5+f[u]+1.000);
        dfs_(v);
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=2;i<=n;i++){
        scanf("%d",&u);
        add(u,i);
    }
    dfs(1);
    f[1]=1.000;
    dfs_(1);
    for(int i=1;i<=n;i++){
        printf("%.2lf ",f[i]);
    }
    return 0;
}

3.【xsy2410】[CF486D]有效集合

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define modHA 1000000007LL
using namespace std;
struct edge{
    int v,next;
}a[500001];
int d,n,u,v,tot=0,num[100001],head[100001];
long long ans=0ll,f[100001];
void add(int u,int v){
    a[++tot].v=v;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u,int fa,int rt){
    f[u]=1;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa&&!(num[v]>num[rt]||num[rt]-num[v]>d)&&!(num[v]==num[rt]&&v<rt)){
            dfs(v,u,rt);
            f[u]=f[u]*(f[v]+1)%modHA;
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d%d",&d,&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&num[i]);
    }
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    for(int i=1;i<=n;i++){
        dfs(i,0,i);
        ans=(ans+f[i])%modHA;
    }
    printf("%lld",ans);
    return 0;
}

4.【xsy2411】[CF161D]Distance in Tree

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int v,next;
}a[500001];
int n,k,u,v,tot=0,ans=0,f[50001][501],head[100001];
void add(int u,int v){
    a[++tot].v=v;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u,int fa){
    f[u][0]=1;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa){
            dfs(v,u);
            for(int i=0;i<k;i++){
                ans+=f[u][i]*f[v][k-i-1];
            }
            for(int i=1;i<=k;i++){
                f[u][i]+=f[v][i-1];
            }
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs(1,0);
    printf("%d",ans);
    return 0;
}

将做

1.【xsy2117】摩尔庄园
2.【xsy2407】[CF708C]Centroids

树上倍增

已做

0.模板(LCA)。。。
1.【xsy2018】[NOIP2013] 货车运输

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge{
    int u,v,w;
}a[1000001];
struct ed{
    int v,w,next;
}e[1000001];
int n,m,q,u,v,w,tot=0,p[16],dep[100001],fa[100001],f[10001][16],minn[10001][16],head[100001];
bool cmp(edge a,edge b){
    return a.w>b.w;
}
int ff(int u){
    return u==fa[u]?u:fa[u]=ff(fa[u]);
}
void add(int u,int v,int w){
    e[++tot].v=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot;
}
void mst_k(){
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=m;i++){
        int x1=ff(a[i].u),x2=ff(a[i].v);
        if(x1!=x2){
            add(a[i].u,a[i].v,a[i].w);
            add(a[i].v,a[i].u,a[i].w);
            fa[x1]=x2;
        }
    }
}
void cal_dep(int u){
    dep[u]=dep[f[u][0]]+1;
    for(int i=1;p[i]<=n;i++){
        f[u][i]=f[f[u][i-1]][i-1];
        minn[u][i]=min(minn[u][i-1],minn[f[u][i-1]][i-1]);
    }
    for(int tmp=head[u];tmp!=-1;tmp=e[tmp].next){
        int v=e[tmp].v;
        if(v!=f[u][0]){
            f[v][0]=u;
            minn[v][0]=e[tmp].w;
            cal_dep(v);
        }
    }
}
int lca(int u,int v){
    if(dep[u]<dep[v]){
        swap(u,v);
    }
    for(int i=14;i>=0;i--){
        if(p[i]<=dep[u]-dep[v])u=f[u][i];
    }
    if(u==v)return u;
    for(int i=14;i>=0;i--){
        if(f[u][i]!=f[v][i]){
            u=f[u][i];
            v=f[v][i];
        }
    }
    return f[u][0];
}
int query(int u,int v,int l){
    int ans=0x7f7f7f7f;
    for(int i=14;i>=0;i--){
        if(p[i]<=dep[u]-dep[l]){
            ans=min(ans,minn[u][i]);
            u=f[u][i];
        }
    }
    for(int i=14;i>=0;i--){
        if(p[i]<=dep[v]-dep[l]){
            ans=min(ans,minn[v][i]);
            v=f[v][i];
        }
    }
    return ans;
}
int main(){
    memset(head,-1,sizeof(head));
    memset(minn,0x7f,sizeof(minn));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
    }
    p[0]=1;
    for(int i=1;i<=14;i++){
        p[i]=p[i-1]*2;
    }
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    mst_k();
    dep[1]=1;
    f[1][0]=0;
    cal_dep(1);
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&u,&v);
        int u1=ff(u),v1=ff(v);
        if(u1!=v1){
            printf("-1\n");
            continue;
        }
        printf("%d\n",query(u,v,lca(u,v)));
    }
    return 0;
}

2.【xsy2413】[JLOI2012]树

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,s,u,v,ans=0,num[100001],fa[100001];
int main(){
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",&num[i]);
    }
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        fa[v]=u;
    }
    for(int i=1;i<=n;i++){
        u=i;
        v=0;
        while(v<=s&&u!=0){
            v+=num[u]; 
            u=fa[u];
            if(v==s)ans++;
        }
    }
    printf("%d",ans);
    return 0;
}

将做

太多了不写了

树状数组

已做

1.【xsy2428】[Cqoi2010]内部白点

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lowbit(n) (n&-n)
using namespace std;
struct node{
    int x,y;
}a[100001];
struct link{
    int x,y,k,r;
}s[1000001];
int n,ans,tot=0,h[100001],tree[400001];
bool cmp(node a,node b){
    return a.x==b.x?a.y<b.y:a.x<b.x;
}
bool cmp_(node a,node b){
    return a.y==b.y?a.x<b.x:a.y<b.y;
}
bool _cmp_(link a,link b){
    return a.y==b.y?a.k<b.k:a.y<b.y;
}
void add(int u,int val){
    for(;u<=n;u+=lowbit(u)){
        tree[u]+=val;
    }
}
int query(int u){
    int ans=0;
    for(;u>0;u-=lowbit(u)){
        ans+=tree[u];
    }
    return ans;
}
int ff(int u){
    int l=1,r=n,mid;
    while(l<=r){
        mid=(l+r)/2;
        if(h[mid]<u)l=mid+1;
        else if(h[mid]>u)r=mid;
        else return mid;
    }
}
void ins(bool ch,int l,int r,int ss){
    if(!ch){
        s[++tot].x=ff(l);
        s[tot].y=ss;
        s[tot].r=ff(r);
        s[tot].k=0;
    }else{
        s[++tot].x=ff(ss);
        s[tot].y=l;
        s[tot].k=1;
        s[++tot].x=ff(ss);
        s[tot].y=r;
        s[tot].k=-1;
    }
}
int main(){
    memset(tree,0,sizeof(tree));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        h[i]=a[i].x;
    }
    sort(h+1,h+n+1);
    sort(a+1,a+n+1,cmp);
    for(int i=2;i<=n;i++){
        if(a[i].x==a[i-1].x){
            ins(true,a[i-1].y,a[i].y,a[i].x);
        }
    }
    sort(a+1,a+n+1,cmp_);
    for(int i=2;i<=n;i++){
        if(a[i].y==a[i-1].y){
            ins(false,a[i-1].x,a[i].x,a[i].y);
        }
    }
    sort(s+1,s+tot+1,_cmp_);
    for(int i=1;i<=tot;i++){
        if(s[i].k==0){
            ans+=query(s[i].r-1)-query(s[i].x);
        }else{
            add(s[i].x,s[i].k);
        }
    }
    printf("%d",ans+n);
    return 0;
}

2.【xsy2429】isn

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lowbit(n) (n&-n)
#define modHA 1000000007
typedef long long ll;
using namespace std;
ll n,ans=0,a[2001],b[2001],tree[2001][2001],f[2001][2001],dc[2001],p[2001];
void add(ll u,ll v,ll val){
    for(;v<=n;v+=lowbit(v)){
        tree[u][v]=(tree[u][v]+val)%modHA;
    }
}
ll query(ll u,ll v){
    int ans=0;
    for(;v>0;v-=lowbit(v)){
        ans=(ans+tree[u][v])%modHA;
    }
    return ans%modHA;
}
int main(){
    memset(dc,0,sizeof(dc));
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        b[i]=a[i];
    }
    p[0]=1;
    for(int i=1;i<=n;i++){
        p[i]=(p[i-1]*i)%modHA;
    }
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(b+1,b+n+1,a[i])-b;
    }
    add(0,1,1);
    for(int i=1;i<=n;i++){
        for(int j=i;j>=1;j--){
            f[i][j]=query(j-1,a[i])%modHA;
            add(j,a[i],f[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            dc[i]=(dc[i]+f[j][i])%modHA;
        }
    }
    for(int i=1;i<=n;i++){
        ans=(((ans+dc[i]*p[n-i])%modHA-dc[i+1]*p[n-i-1]%modHA*(i+1)%modHA)%modHA+modHA)%modHA;
    }
    printf("%lld",ans);
    return 0;
}

3.【xsy2430】[cf341D]Iahub and Xors

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lowbit(n) (n&-n)
typedef long long ll;
using namespace std;
ll n,m,a,b,c,d,e,f,ans=0,tree[2][2][1001][1001];
void add(ll u,ll v,ll val){
    int uu=u&1,vv=v&1;
    for(;u<=n;u+=lowbit(u)){
        for(;v<=n;v+=lowbit(v)){
            tree[uu][vv][u][v]^=val;
        }
    }
}
int query(ll u,ll v){
    int uu=u&1,vv=v&1,ans=0;
    for(;u>0;u-=lowbit(u)){
        for(;v>0;v-=lowbit(v)){
            ans^=tree[uu][vv][u][v];
        }
    }
    return ans;
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&e);
        if(a==1){
            ans=query(d,e);
            if(b>1)ans^=query(b-1,e);
            if(c>1)ans^=query(d,c-1);
            if(b>1&&c>1)ans^=query(b-1,c-1);
            printf("%lld\n",ans);
        }else{
            scanf("%lld",&f);
            add(d+1,e+1,f);
            add(b,e+1,f);
            add(d+1,c,f);
            add(b,c,f);
        }
    }
    return 0;
}

4.【xsy2431】[cf597C]子序列

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lowbit(n) (n&-n)
using namespace std;
typedef long long ll;
ll n,k,a[100001],tree[100001][21];
void add(ll u,ll v,ll val){
    for(;u<=n+1;u+=lowbit(u)){
        tree[u][v]+=val;
    }
}
ll query(ll u,ll v){
    ll ans=0;
    for(;u>0;u-=lowbit(u)){
        ans+=tree[u][v];
    }
    return ans;
}
int main(){
    memset(tree,0,sizeof(tree));
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    add(1,0,1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=k+1;j++){
            add(a[i]+1,j,query(a[i],j-1));
        }
    }
    printf("%lld",query(n+1,k+1));
    return 0;
}

将做

1.【xsy2432】[BZOJ2819] Nim
2.【xsy2433】[BZOJ3155]Preprefix sum

树链剖分

已做

1.【xsy1129】flow
树剖求链+线段树优化建图+最大流最小割

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
struct node{
    int f,v,k,p;
}aa[100001];
struct edge_dinic{
    int v,w,op,next;
}a[5000001];
struct edge_tree{
    int v,next;
}a1[100001];
int n,tot=0,tot1=0,sum=0,vs,vt,tim=0,ans=0,siz[100001],dfn[100001],top[100001],dep[100001],son[100001],tree[100001],nm1[100001],lv[1000001],head[1000001],head1[1000001];
void add(int u,int v){
    a1[++tot1].v=v;
    a1[tot1].next=head1[u];
    head1[u]=tot1;
}
void add1(int u,int v,int w){
    a[++tot].v=v;
    a[tot].w=w;
    a[tot].op=tot+1;
    a[tot].next=head[u];
    head[u]=tot;
    a[++tot].v=u;
    a[tot].w=0;
    a[tot].op=tot-1;
    a[tot].next=head[v];
    head[v]=tot;
}
void dfs(int u){
    siz[u]=1;
    son[u]=0;
    for(int tmp=head1[u];tmp!=-1;tmp=a1[tmp].next){
        int v=a1[tmp].v;
        if(v!=aa[u].f){
            dep[v]=dep[u]+1;
            dfs(v);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])son[u]=v;
        }
    }
}
void dfs_(int u,int top_){
    dfn[u]=++tim;
    nm1[tim]=u;
    top[u]=top_;
    if(son[u]){
        dfs_(son[u],top_);
    }
    for(int tmp=head1[u];tmp!=-1;tmp=a1[tmp].next){
        int v=a1[tmp].v;
        if(v!=aa[u].f&&v!=son[u]){
            dfs_(v,v);
        }
    }
}
void build(int l,int r,int u){
    sum=max(sum,u);
    if(l==r){
        tree[nm1[l]]=u;
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,u*2);
    build(mid+1,r,u*2+1);
    add1(u,u*2,0x7f7f7f7f);
    add1(u,u*2+1,0x7f7f7f7f);
}
void query(int l,int r,int u,int L,int R,int val){
    if(L<=l&&r<=R){
        add1(val,u,0x7f7f7f7f);
        return;
    }
    int mid=(l+r)/2;
    if(L<=mid)query(l,mid,u*2,L,R,val);
    if(R>mid)query(mid+1,r,u*2+1,L,R,val);
}
void work(int x,int y){
    int cnt=y;
    y=aa[y].f;
    while(true){
        int depth=dep[y]-dep[top[y]]+1;
        if(depth<x){
            x-=depth;
            query(1,n,1,dfn[top[y]],dfn[y],cnt+sum);
            y=aa[top[y]].f;
        }else{
            query(1,n,1,dfn[y]-x+1,dfn[y],cnt+sum);
            break;
        }
    }
}
bool bfs(){
    queue<int>q;
    memset(lv,0,sizeof(lv));
    lv[vs]=1;
    q.push(vs);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
            int v=a[tmp].v;
            if(a[tmp].w!=0&&lv[v]==0){
                lv[v]=lv[u]+1;
                if(v==vt)return true;
                q.push(v);
            }
        }
    }
    return false;
}
int dfs__(int u,int l){
    int anss=0;
    if(u==vt||!l)return l;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v,flow;
        if(lv[v]==lv[u]+1){
            flow=dfs__(v,min(l,a[tmp].w));
            anss+=flow;
            l-=flow;
            a[tmp].w-=flow;
            a[a[tmp].op].w+=flow;
            if(!l)break;
        }
    }
    if(anss==0)lv[u]=0;
    return anss;
}
int main(){
    memset(head1,-1,sizeof(head1));
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d%d",&aa[i].f,&aa[i].v,&aa[i].k,&aa[i].p);
        if(aa[i].f){
            add(i,aa[i].f);
            add(aa[i].f,i);
        }
    }
    dep[1]=0;
    dfs(1);
    dfs_(1,1);
    build(1,n,1);
    vs=0;
    vt=n+sum+1;
    for(int i=1;i<=n;i++){
        if(aa[i].v>=0){
            add1(vs,tree[i],aa[i].v);
            ans+=aa[i].v;
        }else{
            add1(tree[i],vt,-aa[i].v);
        }
        add1(tree[i],sum+i,aa[i].p);
        if(aa[i].k)work(aa[i].k,i);
    }
    while(bfs())ans-=dfs__(vs,0x7f7f7f7f); 
    printf("%d",ans);
    return 0;
}

2.【xsy2147】[ZJOI2008] 树的统计

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
struct edge{
    int v,next;
}a[1000001];
struct tree_node{
    int s,mx;
}tree[1000001];
int n,u,v,q,tot=0,tim=0,head[1000001],son[1000001],fa[1000001],w[1000001],dfn[1000001],dep[1000001],siz[1000001],top[1000001],nm[1000001];
char ord[10];
void add(int u,int v){
    a[++tot].v=v;
    a[tot].next=head[u];
    head[u]=tot;
}
void dfs(int u){
    siz[u]=1;
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa[u]){
            dep[v]=dep[u]+1;
            fa[v]=u;
            dfs(v);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])son[u]=v;
        }
    }
}
void dfs_(int u,int f){
    dfn[u]=++tim;
    top[u]=f;
    if(son[u]==0)return;
    dfs_(son[u],f);
    for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
        int v=a[tmp].v;
        if(v!=fa[u]&&v!=son[u]){
            dfs_(v,v);
        }
    }
}
void updata(int l,int r,int u,int s,int val){
    if(l==r){
        tree[u].mx=val;
        tree[u].s=val;
        return;
    }
    int mid=(l+r)/2;
    if(s<=mid)updata(l,mid,u*2,s,val);
    else updata(mid+1,r,u*2+1,s,val);
    tree[u].s=tree[u*2].s+tree[u*2+1].s;
    tree[u].mx=max(tree[u*2].mx,tree[u*2+1].mx);
}
int qmax(int l,int r,int u,int L,int R){
    if(L<=l&&r<=R){
        return tree[u].mx;
    }
    int mid=(l+r)/2,ans=-0x7f7f7f7f;
    if(L<=mid)ans=max(ans,qmax(l,mid,u*2,L,R));
    if(R>mid)ans=max(ans,qmax(mid+1,r,u*2+1,L,R));
    return ans;
}
int q_max(int u,int v){
    int ans=-0x7f7f7f7f;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        ans=max(ans,qmax(1,n,1,dfn[top[u]],dfn[u]));
        u=fa[top[u]];
    }
    if(dfn[u]>dfn[v])swap(u,v);
    ans=max(ans,qmax(1,n,1,dfn[u],dfn[v]));
    return ans;
}
int qsum(int l,int r,int u,int L,int R){
    if(L<=l&&r<=R){
        return tree[u].s;
    }
    int mid=(l+r)/2,ans=0;
    if(L<=mid)ans+=qsum(l,mid,u*2,L,R);
    if(R>mid)ans+=qsum(mid+1,r,u*2+1,L,R);
    return ans;
}
int q_sum(int u,int v){
    int ans=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        ans+=qsum(1,n,1,dfn[top[u]],dfn[u]);
        u=fa[top[u]];
    }
    if(dfn[u]>dfn[v])swap(u,v);
    ans+=qsum(1,n,1,dfn[u],dfn[v]);
    return ans;
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&w[i]);
    }
    for(int i=1;i<=n*4;i++){
        tree[i].mx=-0x7f7f7f7f;
    }
    dep[1]=1;
    fa[1]=0;
    dfs(1);
    dfs_(1,1);
    for(int i=1;i<=n;i++){
        updata(1,n,1,dfn[i],w[i]);
    }
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%s%d%d",ord,&u,&v);
        if(ord[0]=='C'){
            updata(1,n,1,dfn[u],v);
        }else if(ord[0]=='Q'&&ord[1]=='M'){
            printf("%d\n",q_max(u,v));
        }else{
            printf("%d\n",q_sum(u,v));
        }
    }
    return 0;
}

将做

太多了不写了

总结

这几天集训其实很腐(CS+看Seed-D+每天2h农药),加上自己晚来一天,总是感觉做的题很少,又追不上同学的速度。。。(代码一些也是抄solution||网上的,感觉自己要AFO了)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值