【前方高能】填坑_垃圾桶

本篇文章是辣鸡的博主记录没有A的题和没有调出的代码,还有一些奇奇怪怪的东西;
坑是要一个一个填的;

残码

sb扫雷dfs,肯定不是大量的分类讨论啊,,应该是枚举递归,然后不合法就剪掉

void dfs(int num)
{
    if (num>n) {ans++; return;}
    if (num==1) 
    {
        if (a[1]==0) vis[1]=0;
        if (a[1]==1) 
    }
    if (a[num+1]==0)
    {
        vis[num]=0; vis[num+1]=0; vis[num+2]=0; dfs(num+3);
    }
    if (a[num+1]==1)
    {
        if (vis[num]==0 || vis[num]==-1) {
            vis[num]=0; vis[num+1]=1; vis[num+2]=0; dfs(num+3);
            vis[num]=0; vis[num+1]=0; vis[num+2]=1; dfs(num+3);}
        if (vis[num]==1 || vis[num]==-1) {vis[num]=1; vis[num+1]=0; vis[num+2]=0; dfs(num+3);}
    }
    if (a[num+1]==2)
    {

    }
}

0403 sb HH 维护差量肯定会T,还不知道那个地方写Ci了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2e6;
const int inf=1e9;

int n,m,a[maxn],c[maxn],tot,ans[maxn];//c桶 
struct QQ{
    int x,y,id;
}qq[maxn];

bool cmp(QQ x,QQ y) {if (x.y==y.y) return x.x<y.x; return x.y<y.y;}

void add(int l,int r)
{
    for (int j=l; j<=r; j++)
        if (!c[a[j]]) {c[a[j]]++; tot++;}
        else c[a[j]]++;
}
void jian(int l,int r)
{
    for (int j=l; j<=r; j++)
        if (c[a[j]]==1) {c[a[j]]--; tot--;}
        else c[a[j]]--;
}

int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    scanf("%d",&m);
    for (int i=1; i<=m; i++)
    {
        qq[i].id=i; scanf("%d%d",&qq[i].x,&qq[i].y);
    }
    sort(qq+1,qq+1+m,cmp);
//  for (int i=1; i<=m; i++) printf("%d: %d %d\n",i,qq[i].x,qq[i].y);
    add(qq[1].x,qq[1].y); ans[1]=tot; 
    for (int i=2; i<=m; i++)
    {
        add(qq[i-1].y+1,qq[i].y);
        if (qq[i-1].y<=qq[i].x) {jian(qq[i-1].x,qq[i-1].y); add(qq[i].x,qq[i].y);}
        else if (qq[i-1].x<qq[i].x) jian(qq[i-1].x,qq[i].x-1);
        else add(qq[i].x,qq[i-1].x-1);
        ans[qq[i].id]=tot;
    }
    for (int i=1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

20180403
R1前的HU测,loli非让高一的也考我爆零了
T1 yali集训,比较好的一道题
给定字符串 S 和 T, 定义两个字符串匹配当且仅当每种字符的数量相等, 求 S 的哪些连续子串与 T 匹配.
字符集大小,字符串S,T长度小于等于100w;

这个题面不大完整,他要求的匹配是指对应位置的在各自字符串中都是同一种数;
例如 3 1 3 和2 4 2,3和2对应,1和4对应,所以匹配;
3 3 1和2 4 2虽然数目相等,但位置不匹配;

记录到前一个相同字符的距离

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ans_stk[1000010],top;
int S[1000010],T[1000010],b[1000010];
int LAST[1000010],lasS[1000010],lasT[1000010];
int fail[1000010];
int n,m,C;
void work();
void make_fail(int );
bool cmpS(int x,int y){
    return S[x]<S[y];
}
bool cmpT(int x,int y){
    return T[x]<T[y];
}

void shuchu(int *A,int n)
{
    for (int i=0; i<n; i++) printf("%d ",A[i]); printf("\n");
}

int main()
{
//  freopen("xiz.in","r",stdin);
//  freopen("xiz.out","w",stdout);
    int T;
    scanf("%d%d",&T,&C);
    while(T--)
        work();
}

void work()
{
    int i,j,k,p1,p2;
    top=0;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++) scanf("%d",&S[i]);
    for(i=0;i<m;i++) scanf("%d",&T[i]);
    if(m>n) { printf("0\n");return;}
    for(i=0;i<n;i++) b[i]=i;
    sort(b,b+n,cmpS);//相当于把S从小到大排了序 
    j=0,k=-1;
    for(i=0;i<n;i++)
    {
        if(k!=S[b[i]])  j++,k=S[b[i]];
        S[b[i]]=j;
    }

    for(i=0;i<m;i++) b[i]=i;
    sort(b,b+m,cmpT);
    j=0,k=-1;
    for(i=0;i<m;i++)
    {
        if(k!=T[b[i]])
            j++,k=T[b[i]];
        T[b[i]]=j;
    }
    //把S和T离散化 
    memset(LAST,-1,sizeof(LAST));
    for(i=0;i<n;i++)
    {
        lasS[i]=LAST[S[i]];
        LAST[S[i]]=i;
    }
    memset(LAST,-1,sizeof(LAST));

    for(i=0;i<m;i++)
    {
        lasT[i]=LAST[T[i]];
        LAST[T[i]]=i;
    }

    make_fail(m);
    p1=0,p2=0;
    while (p2<n)
    {
        if ((p1==-1||(((lasT[p1]-p1==lasS[p2]-p2&&lasT[p1]!=-1&&lasS[p2]!=-1)||(lasT[p1]==-1&&lasS[p2]==-1)||(lasT[p1]==-1&&lasS[p2]!=-1&&p2-lasS[p2]>p1))))&&p1!=m)
            p1++,p2++;
        else
            p1=fail[p1];
        if(p1==m)
        {
            ans_stk[++top]=p2-m+1;
        }
    }
    printf("%d\n",top);
    for(i=1;i<=top;i++)
        printf("%d ",ans_stk[i]);
    printf("\n");
}

void make_fail(int n)
{
    int p=0,i;
    memset(fail,0,sizeof(fail));
    fail[0]=-1;
    for(i=1;i<=n;i++)
    {
        p=fail[i-1];
        while (!((lasT[i-1]-(i-1)==lasT[p]-p&&lasT[i-1]!=-1&&lasT[p]!=-1) || (lasT[p]==-1&&lasT[i-1]==-1) || (lasT[p]==-1&&i-1-lasT[i-1]>p))&&p!=-1)
            p=fail[p];
        fail[i]=p+1;
    }
    shuchu(fail,n+1);
}
/*
3 3
6 3
1 2 1 2 3 2
3 1 3
6 3
1 2 1 2 1 2
3 1 3
6 3
1 1 2 1 2 1
3 1 3
*/

[NOI2005]维护数列非常好的一道题

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int maxn=1e6+10;
const int inf=1e9;
int read() {
    char ch=getchar(); int now=0,f=1;
    while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {now=(now<<1)+(now<<3)+ch-'0'; ch=getchar();}
    return now*f;}

int n,m,sz,rt,cnt,a[maxn],id[maxn],f[maxn],ch[maxn][2];
int sum[maxn],mx[maxn],v[maxn],lx[maxn],rx[maxn],size[maxn];
bool tag[maxn],rev[maxn];//tag标记改变,rev翻转
queue <int> q;

int get(int x) {return ch[f[x]][1]==x;}
void pushup(int x) 
{
    int l=ch[x][0],r=ch[x][1];
    sum[x]=sum[l]+sum[r]+v[x];
    size[x]=size[l]+size[r]+1;
    mx[x]=max(mx[l],max(mx[r],rx[l]+v[x]+lx[r]));
    l=max(lx[l],sum[l]+v[x]+lx[r]);
    r=max(rx[r],sum[r]+v[x]+rx[l]);
}

void pushdown(int x)
{
    for (int i=0; i<=1; i++)
    {
        int son=ch[x][i];
        if (tag[x])
        {
            rev[x]=tag[x]=0;
            if (son) {tag[son]=1; v[son]=v[x]; sum[son]=v[x]*size[son];}
            if (v[x]>=0)
                if (son) lx[son]=rx[son]=mx[son]=sum[son];
            else 
                if (son) {lx[son]=rx[son]=0; mx[son]=v[x];}
        }
    }
    int l=ch[x][0]; int r=ch[x][1];
    if (rev[x])
    {
        rev[x]=0; rev[l]^=1; rev[r]^=1;
        swap(lx[l],rx[l]); swap(lx[r],rx[r]);
        swap(ch[l][0],ch[l][1]); swap(ch[r][0],ch[r][1]);
    }
}

void rotate(int x)
{
    int old=f[x],oldf=f[old],which=get(x);
    ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old;//这两句的意思是:
    ch[x][which^1]=old; f[old]=x;
    f[x]=oldf;//我的爷爷成了我的爸爸
    if (oldf) ch[oldf][ch[oldf][1]==old]=x;
    pushup(old); pushup(x);//分别维护信息 
}

void splay(int x,int goal)
{
    for (int fa; (fa=f[x])!=goal; rotate(x))
        if (f[fa]!=goal)
            rotate(get(x)==get(fa) ? fa:x);
    if (!goal) rt=x;
}

int find(int x,int k)//查询编号
{
    pushdown(x);
    int l=ch[x][0]; int r=ch[x][1];
    if (size[l]+1==l) return x;
    if (size[l]>=k) return find(l,k);
    else return find(r,k-size[l]-1);
}

void recycle(int x)//回收编号
{
    int &l=ch[x][0],&r=ch[x][1];
    if (l) recycle(l);
    if (r) recycle(r);
    q.push(x);
    f[x]=l=r=tag[x]=rev[x]=0;
}

int split(int k,int tot)
{
    int x=find(rt,k); int y=find(rt,k+tot+1);
    splay(x,rt); splay(y,ch[x][1]);
    return ch[y][0];
}

void ques(int k,int tot)
{
    int x=split(k,tot);
    printf("%d\n",sum[x]);
}

void modify(int k,int tot,int val)
{
    int x=split(k,tot); int y=f[x];
    v[x]=val; tag[x]=1; sum[x]=size[x]*val;
    if (val>=0) lx[x]=rx[x]=mx[x]=sum[x];
    else {lx[x]=rx[x]=0; mx[x]=val;}
    pushup(y); pushup(f[y]);
}

void rever(int k,int tot)
{
    int x=split(k,tot),fa=f[x];
    if (!tag[x])
    {
        rev[x]^=1;
        swap(ch[x][0],ch[x][1]);
        swap(lx[x],rx[x]);
        pushup(fa); pushup(f[fa]);
    }
}

void del(int k,int tot)
{
    int x=split(k,tot),fa=f[x];
    recycle(x); ch[fa][0]=0;
    pushup(fa); pushup(f[fa]);
}

void build_tree(int l,int r,int fa)
{
    int mid=(l+r)>>1,now=id[mid],pre=id[fa];
    if (l==r)
    {
        mx[now]=sum[now]=a[l];
        tag[now]=rev[now]=0;
        lx[now]=rx[now]=max(a[l],0);
        size[now]=1;
    }
    else if (l<mid) build_tree(l,mid-1,mid);
    else build_tree(mid+1,r,mid);
    v[now]=a[mid]; f[now]=pre;
    pushup(now);
    ch[pre][mid>=fa]=now;
}

void insert(int k,int tot)
{
    for (int i=1; i<=tot; i++) a[i]=read();
    for (int i=1; i<=tot; i++)
        if (!q.empty()) id[i]=q.front(),q.pop();
        else id[i]=++cnt;
    build_tree(1,tot,0);
    int z=id[(1+tot)>>1];
    int x=find(rt,k+1),y=find(rt,k+2);
    splay(x,rt); splay(y,ch[x][1]);
    f[z]=y; ch[y][0]=z;
    pushup(y); pushup(x);
}

int main()
{
    n=read(); m=read();
    mx[0]=a[1]=a[n+2]=-inf;
    for (int i=1; i<=n; i++) a[i+1]=read();
    for (int i=1; i<=n+2; i++) id[i]=i;
    rt=(n+3)>>1; cnt+=2;
    int k,tot,val; char opt[100];
    while (m--)
    {
        scanf("%s",opt);
        if (opt[0]!='M' || opt[2]!='X') k=read(),tot=read();
        if (opt[0]=='I') insert(k,tot);
        if (opt[0]=='D') del(k,tot);
        if (opt[0]=='M'){
            if (opt[2]=='X') printf("%d\n",mx[rt]);
            else {val=read(); modify(k,tot,val);}
        }
        if (opt[0]=='R') rever(k,tot);
        if (opt[0]=='G') ques(k,tot);
    }
    return 0;
}

[USACO16FEB]负载平衡Load Balancing_Silver
最后通过模拟实现了

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=1e3+100;
const int inf=1e6;

int N,numy,numx,sumy[maxn],hash[maxn],head[maxn];//head索引表 
struct Cow{
    int x,y;
}a[maxn];
bool cmp(Cow x,Cow y) {if (x.x==y.x) return x.y<y.y; return x.x<y.x;}
int sum[maxn<<1|1];

void pushup(int rt) {sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void change(int x,int C,int l,int r,int rt)
{
    if (l==r && x==l) {sum[rt]+=C; return;}
    int mid=(l+r)>>1;
    if (x<=mid) change(x,C,l,mid,rt<<1);
    else change(x,C,mid+1,r,rt<<1|1);
    pushup(rt);
}

int ques(int L,int R,int l,int r,int rt)
{
    if (L<=l && r<=R) return sum[rt];
    int mid=(l+r)>>1; int ans=0;
    if (L<=mid) ans+=ques(L,R,l,mid,rt<<1);
    if (R>mid) ans+=ques(L,R,mid+1,r,rt<<1);
    return ans;
}

void debug(int *b,int len)
{
    printf("%d\n",len);
    for (int i=1; i<=len; i++) printf("%d ",b[i]); printf("\n");
}

int main()
{
    int ans=inf;
    scanf("%d",&N);
    for (int i=1; i<=N; i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        hash[2*i-1]=a[i].x; hash[2*i]=a[i].y;
    }
    sort(hash+1,hash+1+2*N);
    int nn=unique(hash+1,hash+1+2*N)-hash-1;

    for (int i=1; i<=N; i++)
    {
        a[i].x=lower_bound(hash+1,hash+1+nn,a[i].x)-hash;
        a[i].y=lower_bound(hash+1,hash+1+nn,a[i].y)-hash;
        numx=max(numx,a[i].x); numy=max(numy,a[i].y);
    }
    sort(a+1,a+1+N,cmp);
//  for (int i=1; i<=N; i++) printf("%d %d\n",a[i].x,a[i].y);
    for (int i=1; i<=N; i++) if (a[i].x!=a[i-1].x) head[a[i].x]=i; head[numx]=N+1;
//  debug(head,N);
    for (int i=1; i<=N; i++) sumy[a[i].y]++;
    for (int i=1; i<=numy; i++) sumy[i]+=sumy[i-1];
//    debug(sumy,numy);
    for (int i=1; i<=numx; i++)
    {
        if (!head[i]) continue;
        for (int j=head[i]; j<head[i+1]; j++)
            change(a[i].y,1,1,numy,1);
        for (int j=1; j<=numy; j++)
        {
            int minn1=ques(1,j,1,numy,1); int sum1=sum[j]-sum[0];
            int minn2=ques(j+1,numy,1,numy,1); int sum2=sum[numy]-sum[j];
            minn1=max(minn1,sum1-minn1); minn2=max(minn2,sum2-minn2);
            ans=min(ans,max(minn1,minn2));
        }
    }
    printf("%d\n",ans+1);
    return 0;
}
/*
7
7 3
5 5
7 13
3 1
11 7
5 3
9 1
*/

试图通过模拟实现后缀排序

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e6+10;

int n,a[maxn],b[maxn],tot;
char ch[maxn];
int mul(int x)
{
    int ans=0;
    while (x) {x/=10; ans++;}
    return ans;
}
int power(int x) {int ans=1; for (int i=1; i<=x; i++) ans*=10; return ans;}
int main()
{
    scanf("%s",ch);
    n=strlen(ch);
    for (int i=1; i<=n; i++) a[i]=ch[i-1]-'0';
//    for (int i=1; i<=n; i++) printf("%d ",power(mul(a[i])));
    while (tot!=n)
    {
        for (int i=1; i<=n; i++) a[i]=a[i]*power(mul(a[i+1]))+a[i+1];
//      for (int i=1; i<=n; i++) printf("%d ",a[i]); printf("\n");
        for (int i=1; i<=n; i++) b[i]=a[i];
        sort(b+1,b+1+n);
        tot=unique(b+1,b+1+n)-b-1;
//      for (int i=1; i<=tot; i++) printf("%d ",b[i]); printf("\n");
        for (int i=1; i<=n; i++) a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
//      for (int i=1; i<=n; i++) printf("%d ",a[i]); printf("\n"); printf("\n");
    }
    for (int i=1; i<=n; i++) b[a[i]]=i;
    for (int i=1; i<=n; i++) printf("%d ",b[i]);
}
/*
5Q2K2Pz3vL3K5NFJ48Lj77MYpTRo8dq25fS26BUl59i16a9kuxuFu4d477vz0057gB00218hv69C2Wz7Fk5pMt153uVAq3F3rK0T
*/

虔诚的坟墓

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
const int maxn=100001;
const ll mod=2147483647;//+1
int n,m,w,k,sumx[maxn],sumy[maxn],hash[maxn],now[maxn];//now[i]表示当前列选择了几棵树 
ll c[maxn][100],sum[maxn<<1];
struct tree{
    int x,y;
}a[maxn];

bool cmp(tree a,tree b) {if (a.y!=b.y) return a.y<b.y; return a.x<b.x;}//从左往右排 
int read()
{
    char ch=getchar(); int now=0,f=1;
    while (ch<'0' || ch>'9') {ch=getchar(); if (ch=='-') f=-1;}
    while (ch>='0'&&ch<='9')
    {
        now=(now<<1)+(now<<3)+ch-'0';
        ch=getchar();
    }
    return now*f;
}

void pushup(int rt) {sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void change(int rt,int l,int r,int x,int C)
{
    if (l==r) 
    {
        if (C!=0) printf("rt: %d: %d\n",rt,C);
        sum[rt]=C; return;
    }
    int mid=(l+r)>>1;
    if (x<=mid) change(rt<<1,l,mid,x,C);
    else change(rt<<1|1,mid+1,r,x,C);
    pushup(rt);
}

ll ques(int L,int R,int l,int r,int rt)
{
    if (L<=l && r<=R) return sum[rt];
    int mid=(l+r)>>1; ll tot=0;
    if (L<=mid) tot+=ques(L,R,l,mid,rt<<1);
    if (R>mid) tot+=ques(L,R,mid+1,r,rt<<1|1);
    return tot%mod;
}

void find_C(int n,int k)
{
    for (int i=0; i<=n; i++) c[i][i]=c[i][0]=1;
    for (int i=2; i<=n; i++)
        for (int j=1; j<=i; j++)
        {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
        }
}

int x[maxn],y[maxn];
int main()
{
//  freopen("religious.in","r",stdin);
//  freopen("religious.out","w",stdout);

    n=read(); m=read(); w=read(); int tot=0;
    for (int i=1; i<=w; i++)
    {
        x[i]=read(); y[i]=read();
        hash[++tot]=x[i]; hash[++tot]=y[i];
    }
    k=read();
    find_C(w,k);
    sort(hash+1,hash+1+tot);
    int nn=unique(hash+1,hash+1+tot)-hash-1;
//  printf("hash: %d\n",nn);
//  for (int i=1; i<=nn; i++) printf("%d ",hash[i]); printf("\n");
    for (int i=1; i<=w; i++)
    {
        x[i]=lower_bound(hash+1,hash+1+nn,x[i])-hash;
        y[i]=lower_bound(hash+1,hash+1+nn,y[i])-hash;
        sumy[y[i]]++; sumx[x[i]]++;
        n=max(n,x[i]);
        a[i].x=x[i]; a[i].y=y[i];
    }
    sort(a+1,a+1+w,cmp);
    ll ans=0;
    for (int i=1; i<=w; i++)
    {
        int xx=a[i].x; int yy=a[i].y; int num=0;
        if (i!=1 && a[i].y==a[i-1].y)//如果在同一列 
        {
            num++;
            int y1=a[i-1].x+1; int y2=a[i].x-1;
//          printf("%d %d\n",y1,y2);
            if (y1<=y2)//两棵树之间不相邻(有墓地)
            {
                ans=(ans+c[num][k]*c[sumy[yy]-num][k]%mod*ques(y1,y2,1,w,1)%mod)%mod;
//              printf("ans: %lld %lld\n",ans,ques(y1,y2,1,w,1));
            }
        }
        else num=0;
        now[xx]++;
//      printf("%lld %lld\n",c[now[xx]][k],c[sumx[xx]-now[xx]][k]);
        ll C=c[now[xx]][k]*c[sumx[xx]-now[xx]][k]%mod;
//      printf("%lld\n",C);
        ans+=C;
        change(1,1,n,xx,C);
    }
    for (int i=1; i<=50; i++) printf("%d: %d \n",i,sum[i]);
    printf("%lld\n",ans);
    return 0;
}
/*
5 6
13
0 2
0 3
1 2
1 3
2 0
2 1
2 4
2 5
2 6
3 2
3 3
4 3
5 2
2
*/

20180325 [SDOI2008]Sandy的卡片 测试
好多人都用暴力过了这道题我按自己的思路但是ci了,我还是太菜了;
结构体按照长度排序,上下两个序列相邻两个数的差值相同便连边dfs搜索
好像写起来有很多错误

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=200100;//点数 

int n,m,ans=0;
struct Xian{
    int len,v[1001],delta[1001];
}a[1001];
struct Edge{
    int next,to,from;
}edge[1000001];
int num_edge=-1,head[maxn],sum[maxn];//sum 保存前缀数量 

int read()
{
    char ch=getchar(); int now=0,f=1;
    while (ch<'0' || ch>'9') {ch=getchar(); if (ch=='-') f=-1;}
    while (ch>='0'&&ch<='9')
    {
        now=(now<<1)+(now<<3)+ch-'0';
        ch=getchar();
    }
    return now*f;
}
bool cmp(Xian x,Xian y) {return x.len<y.len;}

void add_edge(int from,int to)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].to=to;
    edge[num_edge].from=from;
    head[from]=num_edge;
}

void build_graph()//注意给每个点编号 
{
    for (int i=1; i<=n; i++) sum[i]=sum[i-1]+a[i].len-1;//保存的是delta的长度 
//  printf("sum: "); for (int i=0; i<=n; i++) printf("%d ",sum[i]);
    for (int i=1; i<a[i].len; i++) add_edge(0,i);
    for (int num=1; num<=n-1; num++)
    {
        for (int i=1; i<a[num].len; i++)
            for (int j=1; j<a[num+1].len; j++)
                if (a[num].delta[i]==a[num+1].delta[j])
                {
                    add_edge(sum[num-1]+i,sum[i]+j);
//                  printf("add: %d %d \n",sum[num-1]+i,sum[i]+j);
                }
    }
}

int last[maxn];//保存上一次在这当前序列中选出的数的编号 
bool vis[maxn]; 
void dfs(int num,int x,int len)//num行数 x当前点的编号 len当前的长度 
{
    if (num==n+1) {ans=max(ans,len); dfs(1,last[1]+1,len+1);}
    if (num && last[num] && last[num]!=x-1) return;
    last[num]=x;
    for (int i=head[x]; i!=-1; i=edge[i].next)
    {
        int to=edge[i].to;
        dfs(num+1,to,len);
    }
}

int main()
{
//  freopen("card.in","r",stdin);
//  freopen("card.out","w",stdout);
    memset(head,-1,sizeof(head));
    n=read();
    for (int i=1; i<=n; i++)
    {
        a[i].len=read();
        for (int j=1; j<=a[i].len; j++)
        {
            a[i].v[j]=read();
            if (j!=1) a[i].delta[j-1]=a[i].v[j]-a[i].v[j-1];
        }
    }
    sort(a+1,a+1+n,cmp);
//  for (int i=1; i<=n; i++)
//  {
//      for (int j=1; j<a[i].len; j++) printf("%d ",a[i].delta[j]);
//      printf("\n");
//  }
    build_graph();
//  for (int i=1; i<=num_edge; i++) printf("%d: %d %d\n",i,edge[i].from,edge[i].to);
    dfs(0,0,0);
    printf("%d\n",ans);
    printf("%d",ans+1);//输出长度+1 
    return 0;
}
/*
2
2 1 2
3 4 5 6
*/

换了一种写法发现理解错了题意。
转化成了求n个字符串中最长重合的部分;
还没写对我日他大爷

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=200100;//点数 

int n,m,ans=0;
struct Xian{
    int len,v[1001],delta[1001];
}a[1001];
struct Edge{
    int next,to,from;
}edge[1000001];
int num_edge=-1,head[maxn],sum[maxn];//sum 保存前缀数量 

int read()
{
    char ch=getchar(); int now=0,f=1;
    while (ch<'0' || ch>'9') {ch=getchar(); if (ch=='-') f=-1;}
    while (ch>='0'&&ch<='9')
    {
        now=(now<<1)+(now<<3)+ch-'0';
        ch=getchar();
    }
    return now*f;
}
bool cmp(Xian x,Xian y) {return x.len<y.len;}

bool check(int num,int x,int len)
{
    for (int i=1; i<=a[num].len; i++)
    {
        int tot=0;
        while (a[num].delta[i+tot]==a[1].delta[x+tot])
        {
            tot++; if (tot==len) return true;
        }
    }
    return false;
}
bool judge(int len)
{
    for (int i=1; i<=a[1].len-len+1; i++)
    {
        for (int j=2; j<=n; j++)
            if (!check(j,i,len)) return false;
    }
    return true;
}

int main()
{
//  freopen("card.in","r",stdin);
//  freopen("card.out","w",stdout);
    n=read();
    for (int i=1; i<=n; i++)
    {
        a[i].len=read();
        for (int j=1; j<=a[i].len; j++)
        {
            a[i].v[j]=read();
            if (j!=1) a[i].delta[j-1]=a[i].v[j]-a[i].v[j-1];
        }
        a[i].len--;
    }
    sort(a+1,a+1+n,cmp);
    int l=1,r=a[1].len;
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=a[i].len; j++) printf("%d ",a[i].delta[j]);
        printf("\n");
    }
    while (l<r)  
    {
//      printf("l:%d r:%d\n",l,r);
        int mid=(l+r)>>1;
        if (judge(mid)) l=mid+1;
        else r=mid;
    }
    printf("%d",l+1);//输出长度+1
    return 0;
}
/*
2
2 1 2
3 4 5 9

4
1 2 100 1
5 100 2 100
2 100 2 3 1
3 4 2 100 101

4
5 1 2 4 104 105
6 1 3 103 105 108 109
5 1 6 106 108 208
6 1 4 8 10 110 211


4
1 2 100 1 
2 100 2 3 1
5 100 2 100
3 4 2 100 101

2
4 1 2 103 104
6 4 5 6 107 108 9
*/

[SDOI2009]虔诚的墓主人20180325
考场上写的sb程序

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
const int maxn=100001;
const int mod=2147483647;//+1
int n,m,num,k,hang[5000],lie[5000];
ll c[1001][1001];
bool mp[10000][10000];
struct tree{
    int x,y;
}a[maxn];
int tot;

bool cmpx(tree a,tree b) {if (a.x!=b.x) return a.x<b.x; return a.y<b.y;}
bool cmpy(tree a,tree b) {if (a.y!=b.y) return a.y<b.y; return a.x<b.x;}

int read()
{
    char ch=getchar(); int now=0,f=1;
    while (ch<'0' || ch>'9') {ch=getchar(); if (ch=='-') f=-1;}
    while (ch>='0'&&ch<='9')
    {
        now=(now<<1)+(now<<3)+ch-'0';
        ch=getchar();
    }
    return now*f;
}

void find_C()
{
    for (int i=0; i<=1000; i++) c[i][i]=c[i][0]=1;
    for (int i=2; i<=1000; i++)
        for (int j=1; j<=min(500,i-1); j++)
        {
            c[i][j]=c[i-1][j]+c[i-1][j-1];
            if (c[i][j]== (ll)mod+1) c[i][j]=0;
        }
}

int getleft(int x,int y)
{
    int sum=0; tot++;
    for (int i=0; i<y; i++) if (mp[x][i]) sum++;
    return sum;
}
int getright(int x,int y)
{
    int sum=0; tot++;
    for (int i=y+1; i<=m; i++) if (mp[x][i]) sum++;
    return sum;
}
int getshang(int x,int y)
{
    int sum=0; tot++;
    for (int i=x+1; i<=n; i++) if (mp[i][y]) sum++;
    return sum;
}
int getxia(int x,int y)
{
    int sum=0; tot++;
    for (int i=0; i<x; i++) if (mp[i][y]) sum++;
    return sum;
}

int main()
{
//  freopen("religious.in","r",stdin);
//  freopen("religious.out","w",stdout);

    find_C();
    n=read(); m=read(); num=read();
    for (int i=1; i<=num; i++)
    {
        a[i].x=read(); a[i].y=read();
    }
    k=read();
//  sort(a+1,a+1+num,cmpx);
    for (int i=1; i<=num; i++) hang[a[i].y]++;
//  sort(a+1,a+1+num,cmpy);
    for (int i=1; i<=num; i++) lie[a[i].x]++;
//  for (int i=0; i<=m; i++) printf("%d ",hang[i]); printf("\n");
//  for (int i=0; i<=n; i++) printf("%d ",lie[i]); printf("\n");
    ll ans=0;
    for (int i=0; i<=n; i++)
        for (int j=0; j<=m; j++)
        {
            int l=0,r=0,s=0,x=0;
            if (!mp[i][j])
            {
                if (j<=(m>>1)) {l=getleft(i,j); r=hang[j]-l;}
                else {r=getright(i,j); l=hang[j]-r;}
//              if (i==2 && j==3) printf("lrsx %d %d ",l,r);
                if (l<k || r<k) continue;
                if (i<=(n>>1)) {s=getshang(i,j); x=lie[i]-s;}
                else {x=getxia(i,j); s=lie[i]-x;}
//              if (i==2 && j==3) printf("%d %d\nlie3:   %d",s,x,lie[i]);
                if (x<k || r<k) continue;
//              printf("%d %d\n",i,j);
                ans+=c[l][k]*c[r][k]*c[s][k]*c[x][k]; 
                if (ans == (ll)mod+1) ans=0;

            }
            if (++tot>192608) {printf("%lld",ans); exit(0);}

        }
    printf("%lld",ans);
    return 0;
}
/*
5 6
13
0 2
0 3
1 2
1 3
2 0
2 1
2 4
2 5
2 6
3 2
3 3
4 3
5 2
2
*/

魔术球

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1000001;
const int inf=1e9;
const int big=5000;
queue <int> q;
int n,m,k,maxflow,a[maxn],S,T,ans;
struct Edge{
    int next,to,dis;
}edge[maxn<<1];
int num_edge=-1,head[maxn],cur[maxn],deep[maxn];
int nxt[maxn],pre[maxn];//分别表示点i的前一个点和后一个点是什么 
bool b[maxn];//是否为平方数 

void add_edge(int from,int to,int dis)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].dis=dis;
    edge[num_edge].to=to;
    head[from]=num_edge;
}
void add(int x,int y,int z) {add_edge(x,y,z); add_edge(y,x,0);}

bool bfs(int s,int t)
{
    memset(deep,0x7f,sizeof(deep));
    for (int i=0; i<=t; i++) cur[i]=head[i];
    while (!q.empty()) q.pop();
    q.push(s); deep[s]=0;
    while (!q.empty())
    {
        int now=q.front(); q.pop();
        for (int i=head[now]; i!=-1; i=edge[i].next)
        {
            int to=edge[i].to;
            if (deep[to]>inf && edge[i].dis)
            {
                deep[to]=deep[now]+1;
                q.push(to);
            }
        }
    }
    return deep[t]<inf;
}

int dfs(int now,int t,int limit)
{
    if (now==t || !limit) return limit;
    int flow=0,f;
    for (int i=cur[now]; i!=-1; i=edge[i].next)
    {
        int to=edge[i].to; cur[now]=i;
        if (deep[to]==deep[now]+1 && (f=dfs(to,t,min(limit,edge[i].dis))))
        {
            flow+=f;
            limit-=f;
            edge[i].dis-=f;
            edge[i^1].dis+=f;
            if (!limit && now!=S && to!=T) nxt[now]=to-big; pre[to-big]=now;
            if (!limit) break;
        }
    }
    return flow;
}

void Dinic(int s,int t)
{
    maxflow=0;
    while (bfs(s,t))
        maxflow+=dfs(s,t,inf);
}
bool vis[maxn];
void shuchu(int x)
{
    if (!x) return;//到达了源点 
    if (pre[x]!=x) shuchu(pre[x]);
    vis[x]=1;
    printf("%d ",x);
}

int main()
{
    for (int i=1; i<=1000; i++) b[i*i]=1; 
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    ans=0; int num=0;//ans 球的数量 num柱子的数量 
    T=2*big;
    for (int i=1; i<=100000; i++) nxt[i]=pre[i]=i;
    while (++ans)
    {
        add(S,ans,1); add(ans+big,T,1);
        for (int i=1; i<ans; i++)
        if (b[i+ans]){
            add(i,ans+big,1);}
//      if (!tot) if (++num>n) break; //这个点加不上了 
        printf("edge\n");
        for (int i=0; i<=num_edge; i++) printf("%d: %d %d %d\n",i,edge[i^1].to,edge[i].to,edge[i].dis);
        Dinic(S,T);
        printf("maxflow: %d\n",maxflow);
        if (maxflow>n) break;
    }
    printf("%d",ans-1);//maxflow+1
    for (int i=n; i>=1; i--)
        if (nxt[i]==i && !vis[i]) {shuchu(i); printf("\n");}
    return 0;
}

poj3764

//题目大意:一棵树中任意两点之间路径的最大异或和
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=100007;

int head[MAXN],num_edge;
int n,d[6000000][2],num[MAXN],cnt;
bool b[MAXN];
struct Edge{
    int next,dis,to;
}edge[MAXN<<2];

void add_edge(int from,int to,int dis)
{
    edge[num_edge].next=head[from];
    edge[num_edge].dis=dis;
    edge[num_edge].to=to;
    head[from]=num_edge++;
}

void dfs(int x,int w)
{
    b[x]=true;
    num[x]=w;
    for (int i=head[x]; i!=0; i=edge[i].next)
    {
        if (!b[edge[i].to])
            dfs(edge[i].to,w^edge[i].dis);
    }
}

void add(int x)
{
    int p=1;
    for (int i=30; i>=0; i--)
    {
        if (d[p][(x>>i)&1]==0) d[p][(x>>i)&1]=++cnt;
        p=d[p][(x>>i)&1];
    }
}

int find(int x)
{
    int p=1,ans=0;
    for (int i=30; i>=0; i--)
    {
        int t=(x>>i)&1;
        if (d[p][1^t])
        {
            ans+=(1<<i);
            p=d[p][1^t];
        }
        else p=d[p][t];
    }
    return ans;
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        num_edge=0;
        memset(head,0,sizeof(head));
        memset(edge,0,sizeof(edge));
        memset(b,0,sizeof(b));
        cnt=1;
        int x,y,z;
        for (int i=1; i<n; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y,z); add_edge(y,x,z);
        }
        dfs(0,0);
        int ans=0;
        for (int i=0; i<n; i++)
        {
            add(num[i]);
            ans=max(ans,find(num[i]));
        }
        printf("%d\n",ans);
    }
    return 0;
}

20180308mhr的暴力
[SCOI2010]序列操作

20180321美食节动态加点

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1000100;
const int inf=1e9;

int n,m,s,t,maxflow,mincost,sum,p[maxn];
struct Edge{
    int next,to,dis,flow;
}edge[maxn<<1];
int num_edge=-1,head[maxn],pre[maxn],dis[maxn],flow[maxn],last[maxn];
int mp[101][101];

void add_edge(int from,int to,int flow,int dis)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].dis=dis;
    edge[num_edge].flow=flow;
    edge[num_edge].to=to;
    head[from]=num_edge;
}
void add(int x,int y,int z,int f) {add_edge(x,y,z,f); add_edge(y,x,0,-f);}
bool vis[maxn];
queue <int> q;
bool spfa(int s,int t)
{
    memset(dis,0x7f,sizeof(dis));
    memset(flow,0x7f,sizeof(flow));
    memset(vis,0,sizeof(vis));
    q.push(s); vis[s]=1; pre[t]=-1; dis[s]=0;

    while (!q.empty())
    {
        int now=q.front(); q.pop();
        vis[now]=0;
        for (int i=head[now]; i!=-1; i=edge[i].next)
        {
            if (edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis)//正边 
            {
                dis[edge[i].to]=dis[now]+edge[i].dis;
                flow[edge[i].to]=min(flow[now],edge[i].flow);
                pre[edge[i].to]=now;
                last[edge[i].to]=i;
                if (!vis[edge[i].to])
                {
                    vis[edge[i].to]=1;
                    q.push(edge[i].to);
                }
            }
        }
    }
    return pre[t]!=-1;
}

void MCMF(int s,int t)
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {
            int lst=last[now];
            edge[lst].flow-=flow[t];
            edge[lst^1].flow+=flow[t];
            if (edge[lst].to==t && (edge[lst^1].to-n)%sum>0)//找到了一条增广路径 
            {
                int to=edge[lst].to;
                add(edge[lst^1].to+1,t,1,0);
                int peo=(edge[lst^1].to-n)/sum+1,num=(edge[lst^1].to-n)%sum+1;
                for (int i=1; i<=n; i++)
                    add(i,edge[lst].to+1,1,mp[i][peo]*num);
            }
            now=pre[now];
        }
    }
}

int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {scanf("%d",&p[i]); sum+=p[i];}
    int S=0,T=n+m*sum+1;
    for (int i=1; i<=n; i++) add(S,i,p[i],0);
    for (int i=n+1; i<=T-1; i++) add(i,T,1,0);
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
            scanf("%d",&mp[i][j]);
    for (int peo=1; peo<=m; peo++)
    {
        int to=n+(peo-1)*sum+1;//先连每个人做倒数第一个菜 
        add(to,T,1,0);
        for (int cai=1; cai<=n; cai++)
            add(cai,to,1,mp[cai][peo]);
    }
//  for (int i=0; i<=num_edge; i++) printf("%d: %d %d %d %d\n",i,edge[i^1].to,edge[i].to,edge[i].flow,edge[i].dis);
    MCMF(S,T);
    printf("%d",mincost);
    return 0;
}
/*
3 2
3 1 1
5 7
3 6
8 9
*/

想法&乱搞

3.29自己胡乱写了一棵线段树
离散化的时候横纵坐标一起还是分别?
每次扫描一个x就修改,
计算差量

3.28很多人都停课了。。
[ZJOI2007]报表统计
考虑使用大模拟解决问题;我想使用这样一种数据结构
这里写图片描述
每个数下面挂一串,然后可以使用一种head,,,
查询最相近的两个数可是lower_bound
每次insert之后需要更新的答案根据插入的答案不断更新
3.20
网络流是不是数据范围都比较小
3.26
数据范围大的时候可以考虑一种叫做“索引表”的东西,(就像是海港那道题),记录每一维在原数组中的下标,可以达到二维的效果

休盗我图


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值