[挖坑]未解决的题

怎么也过不了的题QAQ

3545: [ONTAK2010]Peaks 写的splay+启发式合并不知为何WA啊QAQ,然而网上都没这么写的。
3083: 遥远的国度 感觉是链剖sb题啊然而就是过不了,submit*20。
1189: [HNOI2007]紧急疏散evacuate 本地测数据全过了,二分网络流傻逼题。交上去WA。
3676: [Apio2014]回文串 正解似乎是manacher。。我不想学。。写的后缀数组在UOJ73分,Subtask#5 TLE了QAQ
贴一份WA代码。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long 
using namespace std;
char s[600005];
int l,len,cc[600005],t1[600005],t2[600005];
ll ans=1;
int sa[600005],rank[600005],height[600005],f[600005][20];
inline bool cmp(int *y,int a,int b,int k)
{
    int arank1=y[a];
    int brank1=y[b];
    int arank2=a+k>=l?-1:y[a+k];
    int brank2=b+k>=l?-1:y[b+k];
    return arank1==brank1&&arank2==brank2;
}   
inline void make_sa()
{
    int *x=t1,*y=t2;
    int m=256;
    for (int i=0;i<m;i++) cc[i]=0;
    for (int i=0;i<l;i++) ++cc[x[i]=s[i]];
    for (int i=1;i<m;i++) cc[i]+=cc[i-1];
    for (int i=l-1;~i;i--) sa[--cc[x[i]]]=i;
    for (int k=1;k<l;k<<=1)
    {
        int p=0;
        for (int i=l-k;i<l;i++) y[p++]=i;
        for (int i=0;i<l;i++) 
            if (sa[i]>=k) y[p++]=sa[i]-k;
        for (int i=0;i<m;i++) cc[i]=0;
        for (int i=0;i<l;i++) ++cc[x[y[i]]];
        for (int i=1;i<m;i++) cc[i]+=cc[i-1];
        for (int i=l-1;~i;i--) sa[--cc[x[y[i]]]]=y[i];
        swap(x,y); m=1; x[sa[0]]=0;
        for (int i=1;i<l;i++)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?m-1:m++;
        if (m>=l) break;
    }
}
inline void make_height()
{
    for (int i=0;i<l;i++) rank[sa[i]]=i;
    int k=0; height[0]=0;
    for (int i=0;i<l;i++)
    {
        if (!rank[i]) continue;
        int j=sa[rank[i]-1];
        if (k) k--;
        while (s[j+k]==s[i+k]) k++;
        height[rank[i]]=k;
    }
}
inline void make_st()
{
    for (int i=0;i<l;i++) f[i][0]=height[i];
    for (int j=1;j<=19;j++)
        for (int i=0;i<l;i++)
            if (i+(1<<j)-1<l)
                f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
inline int find_min(int l,int r)
{
    int t=log2(r-l+1);
    return min(f[l][t],f[r-(1<<t)+1][t]);
}
inline int lcp(int l,int r)
{
    if (l>r) swap(l,r);
    return find_min(l+1,r);
}
inline int ask_pre(int RR,int x)
{
    int L=1,R=RR,ans=RR+1;
    while (L<=R)
    {
        int mid=L+R>>1;
        if (find_min(mid,RR)>=x) ans=mid,R=mid-1; else L=mid+1;
    }
    return ans-1;
}
inline int ask_nxt(int LL,int x)
{
    int L=LL+1,R=l-1,ans=LL;
    while (L<=R)
    {
        int mid=L+R>>1;
        if (find_min(LL+1,mid)>=x) ans=mid,L=mid+1; else R=mid-1;
    }
    return ans;
}
inline void calc(int pos,int Palindromic_len)
{
    int x=rank[pos];
    int l,r;
    l=ask_pre(x,Palindromic_len);
    r=ask_nxt(x,Palindromic_len);
    ans=max(ans,(ll)(r-l+1)*(ll)Palindromic_len);
}
inline void find_Palindromic(int pos1,int pos2)
{
    int l=rank[pos1],r=rank[pos2];
    int Palindromic_len=lcp(l,r);
    if (pos1+pos2==2*len) calc(pos1-Palindromic_len+1,Palindromic_len*2-1);
    else calc(pos1-Palindromic_len,Palindromic_len*2);
}
int main()
{
    scanf("%s",s);
    len=strlen(s);
    s[len]='&';
    for (int i=len+1;i<=2*len;i++) s[i]=s[2*len-i];
    l=2*len+1;
    make_sa();
    make_height(); 
    make_st();
    for (int i=0;i<len;i++)
    {
        find_Palindromic(i,2*len-i);
        if (s[i]==s[i-1]) find_Palindromic(i,2*len+1-i);
    }
    cout << (ans>>1);
    return 0;
}

3677: [Apio2014]连珠线 不会做。。写了一个不能再暴力的暴力在UOJ26分。。看起来正解挺麻烦的样子,像一个分情况讨论的恶心DPQAQ。挖坑。。APIO2014看起来只有73+100+26=199了。
贴暴力走人。。

#include<iostream>
#include<cstdio>
#define inf 1000000007
using namespace std;
int n,ans,cnt;
int f[200005][2];
int head[200005],w[200005];
int next[400005],list[400005],key[400005];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y,int z)
{
    next[++cnt]=head[x];
    head[x]=cnt;
    list[cnt]=y;
    key[cnt]=z;
}
void dp(int x,int fa)
{
    int sumson=0;
    f[x][0]=f[x][1]=0;
    for (int i=head[x];i;i=next[i])
        if (list[i]!=fa)
        {
            w[list[i]]=key[i];
            dp(list[i],x);
            sumson++;
        }
    if (!x) {f[x][1]=-inf; return;}
    for (int i=head[x];i;i=next[i])
        if (list[i]!=fa)
        {
            f[x][1]+=max(f[list[i]][1],f[list[i]][0]);
            if (fa) f[x][1]=max(f[x][1],f[x][0]+f[list[i]][0]+w[x]+w[list[i]]);
            f[x][0]+=max(f[list[i]][1],f[list[i]][0]);
        }
}
int main()
{
    n=read(); 
    for (int i=1;i<n;i++)
    {
        int u=read(),v=read(),z=read();
        insert(u,v,z); insert(v,u,z);
    }
    for (int i=1;i<=n;i++)
        dp(i,0),ans=max(ans,f[i][0]);
    cout << ans;
    return 0;
}

4003: [JLOI2015]城池攻占 写的可并堆一直T。。实在不知道怎么回事调不出来,先挂在这吧。。(原题似乎每个点10s就稳稳过了。。)

#include<iostream>
#include<cstdio>
#define ll long long 
#define inf 1e19
#define N 300005
using namespace std;
int next[N],list[N],head[N];
int root[N],q[N],id[N],l[N],r[N],d[N],deep[N],a[N],c[N],ans1[N],ans2[N];
ll tag_a[N],tag_t[N],v[N],t[N],h[N];
int n,m,cnt,cnt0;
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y)
{
    next[++cnt0]=head[x];
    head[x]=cnt0;
    list[cnt0]=y;
}
inline void mul(int x,ll y)
{
    tag_a[x]*=y; tag_t[x]*=y; v[x]*=y;
}
inline void add(int x,ll y)
{
    tag_a[x]+=y; v[x]+=y;
}
inline void pushdown(int x)
{
    if (l[x]) mul(l[x],tag_t[x]);
    if (r[x]) mul(r[x],tag_t[x]);
    tag_t[x]=1;
    if (l[x]) add(l[x],tag_a[x]);
    if (r[x]) add(r[x],tag_a[x]);
    tag_a[x]=0;
}
inline int merge(int x,int y)
{
    if (!x||!y) return x+y;
    if (v[x]>v[y]) swap(x,y);
    pushdown(x);
    r[x]=merge(r[x],y);
    if (d[r[x]]>d[l[x]]) swap(l[x],r[x]);
    d[x]=d[r[x]]+1;
    return x;
}
inline int new_heap(int i,ll val,int s)
{
    l[++cnt]=r[cnt]=d[cnt]=0; 
    v[cnt]=val; id[cnt]=i; c[cnt]=s;
    tag_t[cnt]=1; tag_a[cnt]=0; 
    return cnt;
}
inline int pop(int x)
{
    pushdown(x);
    return merge(l[x],r[x]);
}
void dfs(int x)
{
    for (int i=head[x];i;i=next[i])
    {
        deep[list[i]]=deep[x]+1;
        dfs(list[i]);
        root[x]=merge(root[x],root[list[i]]);
    }       

    while (v[root[x]]<h[x]&&root[x])
    {
        ans1[x]++; ans2[id[root[x]]]=deep[c[root[x]]]-deep[x];
        root[x]=pop(root[x]);
    }
    if (root[x])
    {
        if (a[x]) mul(root[x],t[x]); else add(root[x],t[x]);
    }
}
inline void work(int x)
{
    for (int i=head[x];i;i=next[i])
        root[x]=merge(root[x],root[list[i]]);
    while (root[x]&&v[root[x]]<h[x])
    {
        ans1[x]++; ans2[id[root[x]]]=deep[c[id[root[x]]]]-deep[x];
        root[x]=pop(root[x]);
    }
    if (root[x])
    {
        if (a[x]) mul(root[x],t[x]); else add(root[x],t[x]);
    }
}
inline void bfs()
{
    int t=0,w=1;
    q[1]=1;
    while (t<w)
    {
        int x=q[++t];
        for (int i=head[x];i;i=next[i])
        {
            deep[list[i]]=deep[x]+1;
            q[++w]=list[i];
        }
    }
    for (int i=n;i;i--) work(q[i]);
}
int main()
{
//  freopen("fall.in","r",stdin);
//  freopen("fall.out","w",stdout);

    n=read(); m=read();
    for (int i=1;i<=n;i++) h[i]=read();
    for (int i=2;i<=n;i++)
    {
        int f=read(); a[i]=read(); t[i]=read();
        insert(f,i);
    }
    for (int i=1;i<=m;i++)
    {
        int v=read(),s=read();
        root[s]=merge(root[s],new_heap(i,v,s));
    }
    bfs();
//  dfs(1);
    while (root[1])
    {
        ans2[id[root[1]]]=deep[c[root[1]]]+1;
        root[1]=pop(root[1]);
    }
    for (int i=1;i<=n;i++) printf("%d\n",ans1[i]);
    for (int i=1;i<=m;i++) printf("%d\n",ans2[i]);
    return 0;
}

3932: [CQOI2015]任务查询系统 主席树维护前缀和,本地测试80分不知道怎么改了。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 5000005 
using namespace std;
int n,m,sz,cnt;
ll ans;
int ls[N],rs[N],size[N];
ll sum[N];
int hash[100005],ys[100005],root[200005];
struct node {int s,t,p;} a[100005];
struct data {int x,v,p;} c[200005];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline bool cmp(node a,node b)
{
    return a.p<b.p;
}
inline bool cmp0(data a,data b)
{
    return a.x<b.x;
}
inline int find(int x)
{
    int l=1,r=cnt;
    while (l<=r)
    {
        int mid=l+r>>1;
        if (hash[mid]==x) return mid;
        else if (hash[mid]<x) l=mid+1;
        else r=mid-1;
    }
}
void update(int l,int r,int x,int &y,int t,int v)
{
    y=++sz;
    size[y]=size[x]+v;
    if (l==r) {sum[y]=sum[x]+hash[t]*v; return;}
    ls[y]=ls[x]; rs[y]=rs[x];
    int mid=l+r>>1;
    if (t<=mid) update(l,mid,ls[x],ls[y],t,v);
    else update(mid+1,r,rs[x],rs[y],t,v);
    sum[y]=sum[ls[y]]+sum[rs[y]];
}
ll query(int l,int r,int x,int k)
{
    int mid=l+r>>1;
    if (l==r) return sum[x];
    if (k==size[x]) return sum[x];
    else if (k<=size[ls[x]]) return query(l,mid,ls[x],k);
    else return sum[ls[x]]+query(mid+1,r,rs[x],k-size[ls[x]]);
}
int main()
{
//  freopen("query.in","r",stdin);
//  freopen("query.out","w",stdout);

    m=read(); n=read();
    for (int i=1;i<=m;i++)
        a[i].s=read(),a[i].t=read(),a[i].p=read();
    sort(a+1,a+m+1,cmp);
    hash[++cnt]=a[1].p;
    for (int i=2;i<=m;i++)
        if (a[i].p!=a[i-1].p) hash[++cnt]=a[i].p;
    for (int i=1;i<=m;i++)
    {
        c[2*i-1].x=a[i].s; c[2*i-1].v=1; c[2*i-1].p=a[i].p;
        c[2*i].x=a[i].t+1; c[2*i].v=-1; c[2*i].p=a[i].p;
    }
    sort(c+1,c+2*m+1,cmp0);
    for (int i=1;i<=(m<<1);i++)
    {
        int t=find(c[i].p);
        update(1,cnt,root[i-1],root[i],t,c[i].v);
        ys[c[i].x]=i;
    }
    for (int i=1;i<=2*m;i++)
        for (int j=c[i].x+1;j<c[i+1].x;j++)
            ys[j]=ys[c[i].x];
    ans=1;
    for (int i=1;i<=n;i++)
    {
        int x=read(),a=read(),b=read(),c=read(),k=1+(ans*a+b)%c;
        if (k>size[root[ys[x]]]) ans=sum[root[ys[x]]];
        else ans=query(1,cnt,root[ys[x]],k);
        printf("%lld\n",ans);
    }
    return 0;
}

4337: BJOI2015 树的同构 开始自己YY了一个,先找到直径,然后转化为链上的hash,结果死活不对。。于是看了Creation[Au]gust的题解明白了标算。。结果又死活调不出来。。于是我就弃疗了。

开始自己写的WA代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define base0 177
#define base 233
#define ll long long
using namespace std;
int m,now_left;
struct node {ll v;int id;} hash[55];
int ans[55];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
struct tree 
{
    int n,cnt,S,T,top;
    int head[55],list[105],next[105];
    int q[55],dis[55],from[55],mark[55],stack[55];
    ll sum[55];
    inline void insert(int x,int y)
    {
        next[++cnt]=head[x];
        head[x]=cnt;
        list[cnt]=y;
    }
    inline void BFS(int s)
    {
        memset(dis,-1,sizeof(dis));
        int t=0,w=1,x;
        q[1]=s; dis[s]=0;
        while (t<w)
        {
            x=q[++t];
            for (int i=head[x];i;i=next[i])
                if (dis[list[i]]==-1)
                {
                    from[list[i]]=x;
                    dis[list[i]]=dis[x]+1;
                    q[++w]=list[i];
                }
        }
    }
    inline void find_max_length_road()
    {
        BFS(1);
        for (int i=1;i<=n;i++) if (dis[i]>dis[S]) S=i;
        from[S]=0;
        BFS(S);
        for (int i=1;i<=n;i++) if (dis[i]>dis[T]) T=i;
    }
    ll calc(int x,ll deep,int fa)
    {
        ll now=deep;
        for (int i=head[x];i;i=next[i])
            if (list[i]!=fa) now+=calc(list[i],deep+1,x)*base0;
        return now;
    }       
    inline void pre()
    {
        for (int i=T;i;i=from[i]) stack[++top]=i;
        for (int i=1;i<=top;i++) mark[stack[i]]=1;
        for (int i=1;i<=top;i++) 
            for (int j=head[stack[i]];j;j=next[j])
                if (!mark[list[j]]) sum[stack[i]]+=calc(list[j],1,stack[i])*base0;
    }
    inline ll get_hash()
    {
        ll t1=0,t2=0;
        for (int i=1;i<=top;i++) t1=t1*base+sum[stack[i]];
        for (int i=top;i;i--) t2=t2*base+sum[stack[i]];
        return min(t1,t2);
    }
};
tree f[55];
inline bool cmp(node a,node b)
{
    return f[a.id].n==f[b.id].n?(a.v==b.v?a.id<b.id:a.v<b.v):f[a.id].n<f[b.id].n;
}
int main()
{
    m=read();
    for (int i=1;i<=m;i++)
    {
        f[i].n=read();
        for (int j=1;j<=f[i].n;j++)
        {
            int fa=read();
            if (fa) f[i].insert(fa,j),f[i].insert(j,fa);
        }
    }
    for (int i=1;i<=m;i++) f[i].find_max_length_road();
    for (int i=1;i<=m;i++) f[i].pre();
    for (int i=1;i<=m;i++) hash[i].id=i,hash[i].v=f[i].get_hash();
    sort(hash+1,hash+m+1,cmp);
    ans[hash[1].id]=hash[1].id;
    now_left=hash[1].id;
    for (int i=2;i<=m;i++) 
    {
        if (hash[i].v!=hash[i-1].v||f[hash[i].id].n!=f[hash[i].id].n) now_left=hash[i].id;
        ans[hash[i].id]=now_left;
    }
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

调不出来的标算

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll unsigned
using namespace std;
int n,m,cnt;
int ct[120],head[120],list[120],next[120];
ll sum[120],stack[120],hash[120][120];
ll base[100]={0,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317};
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y)
{
    next[++cnt]=head[x];
    head[x]=cnt;
    list[cnt]=y;
}
void get_hash(int x,int fa)
{
    ll top=0; stack[++top]=1;
    for (int i=head[x];i;i=next[i])
        if (list[i]!=fa) get_hash(list[i],x),stack[++top]=sum[list[i]];
    sort(stack+1,stack+top+1); sum[x]=0; 
    for (int i=1;i<=top;i++) sum[x]+=stack[i]*base[i];
}
int main()
{
    m=read();
    for (int k=1;k<=m;k++)
    {
        n=ct[k]=read();
        memset(head,0,sizeof(head)); 
        cnt=0;
        for (int i=1;i<=n;i++)
        {
            int fa=read();
            if (fa) insert(i,fa),insert(fa,i);
        }
        for (int i=1;i<=n;i++) get_hash(i,0),hash[k][i]=sum[i];
        sort(hash[k]+1,hash[k]+n+1);
        for (int i=1;i<=k;i++)
            if (ct[i]==n)
            {
                int j=1;
                for (;j<=n;j++) 
                    if (hash[i][j]!=hash[k][j]) break;
                if (j>n) {printf("%d\n",i); break;}
            }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值