【自家测试】2017-12-28

A

题面

.题解传送门

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
#include<cmath>
typedef long long LL; 
using namespace std;
LL st,l,r,k,p,m,ans;

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

struct jz {
    LL a[2][2];
    friend jz operator *(const jz&A,const jz&B) {
        jz ret;
        for(int i=0;i<2;i++) 
            for(int j=0;j<2;j++) {
                ret.a[i][j]=0;
                for(int k=0;k<2;k++) 
                    (ret.a[i][j]+=(A.a[i][k]*B.a[k][j])%p)%=p;
            }
        return ret;
    }
}base,res;

void ksm(LL b) {
    while(b) {
        if(b&1) res=res*base;
        base=base*base;
        b>>=1;
    }
}

void exgcd(LL a,LL b,LL &x,LL &y,LL &d) {
    if(!b) { d=a; x=1; y=0; return;}
    exgcd(b,a%b,y,x,d); y-=a/b*x;
} 

//#define DEBUG
int main() {
#ifdef DEBUG
    freopen("A.in","r",stdin);
    freopen("A.out","w",stdout);
#endif
    int T;
    read(T);
    while(T--) {
        read(st); read(l); read(r); 
        read(k); read(p); read(m);
        st%=p; 
        res.a[0][0]=res.a[1][1]=1;
        res.a[0][1]=res.a[1][0]=0;
        base.a[0][0]=0; base.a[0][1]=1;
        base.a[1][0]=base.a[1][1]=1;
        ksm(k-2); ans=0; m%=p;
        LL w=(m+p-res.a[0][1]*st%p)%p;
        LL a=res.a[1][1]%p;
        LL x,y,d,dd;
        exgcd(a,p,x,y,d);
        if(w%d) puts("0");
        else {
            w/=d;
            exgcd(a/d,p/d,x,y,dd);
            x*=w; x=x%(p/d); 
            if(x<0) x+=(p/d);
            LL ll,rr;
            rr=r>=x?1+((r-x)/(p/d)):0;
            ll=l-1>=x?1+((l-1-x)/(p/d)):0;
            printf("%lld\n",rr-ll);
        }
    }
    return 0;
}
/*
1
2 17 1000000 12345678 123333 123456
*/
View Code

 

B.傻逼数据结构题

题解传送门

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
const int N=500007;
typedef long long LL; 
using namespace std;
int T,n,ti[N],q,sum[N];
multiset<int>s[N];

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

struct node{
    int id,t;
    friend bool operator <(const node &A,const node &B) {
        return A.t<B.t;
    }
}; multiset<node>s1;

multiset<int>s2;

void add(int x,int v) {
    for(int i=x;i<=n;i+=(i&(-i))) 
        sum[i]+=v;
}

int qry(int x) {
    int res=0;
    for(int i=x;i;i-=(i&(-i))) 
        res+=sum[i];
    return res;
}

#define DEBUG
int main() {
#ifdef DEBUG
    freopen("B.in","r",stdin);
    freopen("B.out","w",stdout);
#endif
    read(T);
    while(T--) {
        read(n);
        for(int i=1;i<=n;i++) read(ti[i]);
        read(q);
        while(q--) {
            int now,o,l,r,id;
            read(now); read(o);
            while(s1.size()>0) {
                node tp=*s1.begin();
                if(tp.t>now) break;
                add(tp.id,1); s2.insert(tp.id);
                s1.erase(s1.find(tp));
            }
            if(o==0) {
                read(id);
                s[id].insert(now+ti[id]);
                node tp; tp.id=id; tp.t=now+ti[id];
                s1.insert(tp);
            }
            else if(o==1) {
                if(s2.size()==0) 
                    puts("Yazid is angry.");
                else {
                    int x=*s2.begin();
                    int y=*s[x].begin();
                    s[x].erase(s[x].find(y));
                    s2.erase(s2.find(x));
                    add(x,-1);
                    printf("%d\n",x);
                }
            }
            else if(o==2) {
                read(id);
                if(s[id].size()==0)  
                    puts("YJQQQAQ is angry.");
                else {
                    int x=*s[id].begin();
                    if(x<=now) {
                        puts("Succeeded!");
                        s[id].erase(s[id].find(x));
                        s2.erase(s2.find(id));
                        add(id,-1);
                    }
                    else printf("%d\n",x-now);
                }
            }
            else {
                read(l); read(r);
                printf("%d\n",qry(r)-qry(l-1));
            }
        }
        if(T) {
            memset(sum,0,sizeof(sum));
            s1.clear(); s2.clear();
            for(int i=1;i<=n;i++) s[i].clear();    
        }
    }
    return 0;
}
/*
1
2
1 100
10
1 0 2
2 0 1
3 2 1
4 2 2
5 2 1
200 0 1
201 3 1 2
202 1
203 1
204 1
*/
View Code

 

C.字典树+网络流

给定n个长度小于等于8的二进制数,m个前缀或后缀可以用去消除有这个前缀或后缀的数,每个需要一定代价,问消除全部数的最小代价。

建立正反字典树,叶子节点连上inf的边,最小割。

de了一晚上bug发现后缀插入树中时忘了反过来了。。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
#define inf 0x7fffffff
const int N=100007; 
typedef long long LL;
using namespace std;
int n,m,a[N],v[N];
char s[10];

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

struct edge{
    int u,v,c,f,nx;
    edge(){}
    edge(int u,int v,int c,int f,int nx):u(u),v(v),c(c),f(f),nx(nx){}
}e[N];

int ecnt=1,fir[N],nxt[N],to[N];
void add(int u,int v,int c) {
    e[++ecnt]=edge(u,v,c,0,fir[u]); fir[u]=ecnt;
    e[++ecnt]=edge(v,u,0,0,fir[v]); fir[v]=ecnt;
}

queue<int>que;
int d[N],c[N],cur[N],pr[N];
void bfs(int s,int t) {
    que.push(t);
    for(int i=1;i<=n;i++) d[i]=n;
    d[t]=0;
    while(!que.empty()) {
        int x=que.front();
        que.pop();
        for(int i=fir[x];i;i=e[i].nx) 
            if(e[i].c==0&&d[e[i].v]==n) {
                d[e[i].v]=d[x]+1;
                que.push(e[i].v);
            } 
    }
}

int cal(int s,int t) {
    int fl=inf;
    for(int x=t;x!=s;x=e[pr[x]].u)
        fl=min(fl,e[pr[x]].c-e[pr[x]].f);
    for(int x=t;x!=s;x=e[pr[x]].u) {
        e[pr[x]].f+=fl;
        e[pr[x]^1].f-=fl;
    }
    return fl;
}

int ISAP(int s,int t) {
    bfs(s,t);
    int res=0;
    for(int i=1;i<=n;i++) cur[i]=fir[i],c[d[i]]++;
    for(int x=s;d[x]<n;) {
        if(x==t) {
            res+=cal(s,t);
            x=s;
        }
        int ok=0;
        for(int &i=cur[x];i;i=e[i].nx) 
            if(d[e[i].v]+1==d[x]&&e[i].f<e[i].c) {
                pr[x=e[i].v]=i; ok=1; break;    
            }
        if(!ok) {
            int M=n; cur[x]=fir[x];
            for(int i=fir[x];i;i=e[i].nx) 
                if(e[i].f<e[i].c) M=min(M,d[e[i].v]+1);
            if(!(--c[d[x]])) break;
            c[d[x]=M]++; 
            if(x!=s) x=e[pr[x]].u;
        }
    }
    return res;
}


int tot=2,rt1=1,rt2=2,ch[N][2],q1[10],q2[10];
void insert(int id) {
    int x=rt1,y=rt2;
    for(int i=1;i<=8;i++) {
        if(!ch[x][q1[i]]) ch[x][q1[i]]=++tot; 
        if(!ch[y][q2[i]]) ch[y][q2[i]]=++tot;
        x=ch[x][q1[i]]; 
        y=ch[y][q2[i]];
    }
    add(x,y,inf);
}

void dev(int x) {
    for(int i=1;i<=8;i++) {
        q1[i]=q2[8-i+1]=x%2;
        x/=2;
    }
}

void travel() {
    char o[5];
    scanf("%s%s",o,s); 
    int vv; read(vv);
    int len=strlen(s),x;
    if(o[0]=='P') x=rt2;
    else {
        x=rt1;
        reverse(s,s+strlen(s));
    }
    for(int i=0;i<len;i++) {
        int c=s[i]-'0';
        if(!ch[x][c]) return;
        x=ch[x][c];
    }
    v[x]=(v[x]==0?vv:min(v[x],vv));
}

void dfs(int x,int f) {
    int lc=ch[x][0],rc=ch[x][1];
    if(lc) {
        if(v[lc]) {
            if(f==-1) add(lc,x,v[lc]); 
            else add(x,lc,v[lc]);
        }
        else {
            if(f==-1) add(lc,x,inf);
            else add(x,lc,inf);
        }
        dfs(lc,f);
    }
    if(rc) {
        if(v[rc]) {
            if(f==-1) add(rc,x,v[rc]); 
            else add(x,rc,v[rc]);
        }
        else {
            if(f==-1) add(rc,x,inf);
            else add(x,rc,inf);
        }
        dfs(rc,f);
     }
} 

int main() {
#ifdef DEBUG
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
    read(n); read(m);
    for(int i=1;i<=n;i++) {
        read(a[i]); 
        dev(a[i]);
        insert(i);
    }
    for(int i=1;i<=m;i++) 
        travel();
    dfs(rt1,1); dfs(rt2,-1);
    n=tot;
    int ans=ISAP(rt1,rt2);
    if(ans>=inf||ans<0) printf("-1\n");
    else printf("%d\n",ans);
    return 0;
}
/*
8 7
0 1 2 3 4 5 6 7
P 000001 1
P 0000000 1
S 10 1
S 11 1
S 00 1
S 01 1
P 0000001 3
*/
View Code

 

posted @ 2017-12-28 22:13  啊宸  阅读(155)  评论(0编辑  收藏  举报