[Usaco2015 FEB Gold][2016-2-21]考试总结

来源:互联网 发布:广告优化师 编辑:程序博客网 时间:2024/05/20 14:16

第一题裸四方暴力,一直在想怎么用数据结构优化,期间想到了主席树套二维线段树,然而会爆空间,但是只要从上到下从左到右便可以只要主席树了,然后动态开点就是O(n2logn)的空间,还是对主席树不熟练啊,我毕竟是以前只写过一次的蒟蒻。
第二题AC自动机搞啊,裸裸的,然而我写了个O(n2)居然只超了两个点,考场上,下考后都自以为是O(n)。我果然是无脑工业狗,一看见就开始怒敲AC自动机。
第三题考虑陈丹琪分治,接下来便考虑如何快速求出一条直线是否切割了凸包。对于一个直线方程Ax+By+C=0和点(x,y),如果把点代入方程大于0则在直线上方,小于0反之。问题便转化为了凸包上这些点的最大值和最小值是否同号。
由于上下凸壳的函数值均为单峰函数,考虑三分即可。
此题我调了TM好久,三个错误:
一、以为上凸壳的函数就是上凸的,下凸壳的函数就是下凸的,导致三分挂掉;
二、判断同号时直接相乘判断正负,爆LL;
三、三分的复杂度是以1.5为底的,一个for循环for20遍少了。

#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<cassert>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<climits>#define X first#define Y second#define DB double#define MP make_pair#define LL long long#define pb push_back#define sqr(_) ((_)*(_))#define INF 0x3f3f3f3f#define pii pair<int,int>#define pdd pair<DB,DB>#define ull unsigned LL#define zqf 1000000007#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;const int MAXN=751*751;int n,m,k,T[MAXN],st[10000001],top=0,q,v,cnt;int dp[751][751],sum[750],w[751][751],lc[10000001],rc[10000001],Sum[10000001];void Read(int& x){    x=0;char c;int flag=0;    while(c=getchar())    {        if(c>='0'&&c<='9')x*=10,x+=c-'0',flag=1;        else if(flag)break;    }}void insert(int& root,int l,int r){    cnt++;    if(!root)        root=st[--top];    if(l==r)    {        Sum[root]=(Sum[root]+v)%zqf;        return;    }    int mid=(l+r)>>1;    if(q<=mid)        insert(lc[root],l,mid);    else        insert(rc[root],mid+1,r);    Sum[root]=(Sum[lc[root]]+Sum[rc[root]])%zqf;}int query(int now,int l,int r){    cnt++;    if(!now)return 0;    if(l>=1&&r<=q)    {        return Sum[now];    }    int mid=(l+r)>>1,a=0;    if(1<=mid)        a=(a+query(lc[now],l,mid))%zqf;    if(q>mid)        a=(a+query(rc[now],mid+1,r))%zqf;    return a;}int main(){    freopen("hopscotch.in","r",stdin);    freopen("hopscotch.out","w",stdout);    for(int i=0;i<7000000;i++)st[++top]=i+1;    Read(n);Read(m);Read(k);    dp[1][1]=1;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            Read(w[i][j]);    for(int i=2;i<=n;i++)    {        int SUM=0;        for(int j=2;j<=m;j++)        {            if(i==3&&j==4)                i=3;            sum[j-1]=(sum[j-1]+dp[i-1][j-1])%zqf;            SUM=(sum[j-1]+SUM)%zqf;            q=j-1;v=dp[i-1][j-1];cnt=0;            insert(T[w[i-1][j-1]],1,m);            cnt=0;            dp[i][j]=(SUM-query(T[w[i][j]],1,m))%zqf;            if(dp[i][j]<0)dp[i][j]=(dp[i][j]+zqf)%zqf;        }    }    printf("%d\n",dp[n][m]);}
#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<cassert>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<climits>#define X first#define Y second#define DB double#define MP make_pair#define LL long long#define pb push_back#define sqr(_) ((_)*(_))#define INF 0x3f3f3f3f#define pii pair<int,int>#define pdd pair<DB,DB>#define ull unsigned LL#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;const int MAXN=2e5;int n,match[MAXN],flag=0,next[MAXN],from[MAXN],jg=0,M,st[MAXN],top;char s[MAXN],tmp[MAXN];struct ACM{    int son[MAXN][27],f[MAXN],last[MAXN],val[MAXN],tot,Len[MAXN];    ACM(){        memset(son,0,sizeof(son));        memset(f,0,sizeof(f));        memset(last,0,sizeof(last));        memset(val,0,sizeof(val));        tot=0;    }    int idx(char c)    {        return c-'a';    }    void insert(char* S)    {        int m=strlen(S+1),u=0;        for(int i=next[0];i<=m;i=next[i])        {            int v=idx(S[i]);            if(!son[u][v])                son[u][v]=++tot;            u=son[u][v];        }        val[u]=1;        Len[u]=m;    }    void getFail()    {        queue<int> q;        for(int i=0;i<26;i++)        {            if(son[0][i])            {                q.push(son[0][i]);                f[son[0][i]]=last[son[0][i]]=0;            }        }        while(!q.empty())        {            int r=q.front();q.pop();            for(int i=0;i<26;i++)            {                int u=son[r][i];                if(!u){son[r][i]=son[f[r]][i];continue;}                q.push(u);                int j=f[r];                while(j&&!son[j][i])j=f[j];                f[u]=son[j][i];                last[u]=val[f[u]]?f[u]:last[f[u]];            }        }    }    void update(int& now,int l,int& p)    {        int cnt=1,o=now,fuck=0;        while(1)        {            ++fuck;            //DEBUG("%d\n",fuck);            if(cnt==l)            {                match[now]=o;                match[o]=now;                break;            }            now=from[now];            cnt++;            p=st[--top];        }        next[from[now]]=next[o];        from[next[o]]=from[now];        now=from[now];        p=st[--top];    }    void find(char* S)    {        ++jg;        //if(jg%10000==0)DEBUG("%d\n",jg);        int j=0,cnt=0;        top=0;        st[++top]=j;        for(int i=next[0];i<=M;i=next[i])        {            ++cnt;            //DEBUG("%d\n",cnt);            int v=idx(S[i]);            j=son[j][v];            st[++top]=j;            if(val[j])            {                flag=1;                update(i,Len[j],j);            }        }    }}Ac;int main(){    freopen("censor.in","r",stdin);    freopen("censor.out","w",stdout);    memset(match,-1,sizeof(match));    scanf("%s",s+1);    M=strlen(s+1);    for(int i=0;i<MAXN;i++)next[i]=i+1,from[i]=i-1;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%s",tmp+1);        Ac.insert(tmp);    }    Ac.getFail();    while(1)    {           Ac.find(s);        if(!flag)break;        flag=0;    }    for(int i=next[0];i<=M;i=next[i])        putchar(s[i]);    puts("");}
#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<cassert>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<climits>#define X first#define Y second#define DB double#define MP make_pair#define LL long long#define pb push_back#define sqr(_) ((_)*(_))#define INF 0x3f3f3f3f#define int LL#define pii pair<int,int>#define pdd pair<DB,DB>#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;const int MAXN=3e5;struct op{    int t,a,b,c;    op(int t=0,int a=0,int b=0,int c=0):t(t),a(a),b(b),c(c){}}oper[MAXN];template<typename T> void Read(T& x){    x=0;int flag=0,sgn=1;char c;    while(c=getchar())    {        if(c=='-')sgn=-1;        else if(c>='0'&&c<='9')x*=10,x+=c-'0',flag=1;        else if(flag)break;    }    x*=sgn;}int n,ans[MAXN],tot=0,p,q;bool cant[MAXN];pii pot[MAXN],ch[MAXN];int cross(const pii& a,const pii& b){    return a.X*b.Y-a.Y*b.X;}pdd operator -(const pii& a,const pii& b){    return MP(a.X-b.X,a.Y-b.Y);}void CovHull(int l,int r){    p=q=0;    sort(pot,pot+tot);    for(int i=0;i<tot;i++){        while(p>1&&cross(ch[p-1]-ch[p-2],pot[i]-ch[p-2])<=0)p--;        ch[p++]=pot[i];    }    q=p;    for(int i=tot-2;i>=0;i--){        while(p>q&&cross(ch[p-1]-ch[p-2],pot[i]-ch[p-2])<=0)p--;        ch[p++]=pot[i];    }    p--;}int sgn(int x){    return x<0?-1:1;}int F(int id,pii P){    return oper[id].a*P.X+oper[id].b*P.Y+oper[id].c;}int UPgetmax(int id,int ql,int qr){    int l=ql,r=qr;    if(qr<ql)return -INF;    for(int i=1;i<=25;i++)    {        int m1=l+(r-l+1)/3,            m2=r-(r-l+1)/3;        if(F(id,ch[m1])>F(id,ch[m2]))            r=m2;        else            l=m1;    }    return max(F(id,ch[r]),F(id,ch[l]));}int Cgetmax(int id,int ql,int qr){    if(ql>qr)        return -INF;    int l=ql,r=qr;    return max(F(id,ch[r]),F(id,ch[l]));}int DOWNgetmin(int id,int ql,int qr){    int l=ql,r=qr;    if(qr<ql)return INF;    for(int i=1;i<=25;i++)    {        int m1=l+(r-l+1)/3,            m2=r-(r-l+1)/3;        if(F(id,ch[m1])<F(id,ch[m2]))            r=m2;        else            l=m1;    }    return min(F(id,ch[r]),F(id,ch[l]));}int Cgetmin(int id,int ql,int qr){    if(ql>qr)return INF;    return min(F(id,ch[ql]),F(id,ch[qr]));}void _cdq_Div_Con(int l,int r){    if(l==r)return;    int mid=(l+r)>>1;    tot=0;    for(int i=l;i<=mid;i++)        if(oper[i].t==1)            pot[tot++]=MP(oper[i].a,oper[i].b);    CovHull(l,r);    if(tot==0)    {        _cdq_Div_Con(mid+1,r);        return;    }    for(int i=mid+1;i<=r;i++)    if(oper[i].t==2&&!cant[i])    {        int mx=max(max(UPgetmax(i,0,q-1),Cgetmax(i,0,q-1)),max(UPgetmax(i,q,p-1),Cgetmax(i,q,p-1))),            mn=min(min(Cgetmin(i,0,q-1),DOWNgetmin(i,0,q-1)),min(DOWNgetmin(i,q,p-1),Cgetmin(i,q,p-1)));        if(ans[i]!=0)            if(mx==0||mx==0||sgn(mx)!=sgn(mn)||sgn(mx)!=sgn(ans[i]))                cant[i]=1;        if(mx==0||mn==0||sgn(mx)*sgn(mn)<0)cant[i]=1;        ans[i]=sgn(mx);    }    _cdq_Div_Con(l,mid);    _cdq_Div_Con(mid+1,r);}   main(){#ifndef ONLINE_JUDGE    freopen("fencing.in","r",stdin);    freopen("fencing.out","w",stdout);#endif    Read(n);Read(q);    for(int i=1;i<=n;i++)    {        int a,b;        Read(a);Read(b);        oper[i]=op(1,a,b,0);    }    for(int i=1;i<=q;i++)    {        int a,b,c,d;        Read(a);        if(a==1)        {            Read(b);Read(c);            oper[n+i]=op(a,b,c,0);        }        else        {            Read(b);Read(c);Read(d);            oper[n+i]=op(a,b,c,-d);        }    }    n+=q;    _cdq_Div_Con(1,n);    for(int i=1;i<=n;i++)        if(oper[i].t==2)        {            if(!cant[i])                puts("YES");            else                puts("NO");        }}
0 0