UOJ Easy Round #6 题解(待续)

来源:互联网 发布:led滚动屏幕软件 编辑:程序博客网 时间:2024/05/20 07:14

  • UER 6票数统计

【UER #6】票数统计

安利了官解http://jiry_2.blog.uoj.ac/blog/1789
很多地方没来得及删,将就着先

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (998244353)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())typedef long long ll;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} int n,m;#define MAXN (5000+10)#define MAXM (5000+30)pi p[MAXM],p2[MAXM],p3[MAXM];void work1(){    int ans=0;    Rep(S,1<<n) {        bool flag=0;        Rep(i,m) {            int a=S%(1<<p[i].se);            int b=S>>(n-p[i].fi);            if(__builtin_popcount(a)==p[i].fi||__builtin_popcount(b)==p[i].se); else {flag=1;break;}        }        if (!flag) {++ans; /*cout<<S<<'x'<<endl;*/}    }    cout<<ans<<endl;}ll C[MAXN][MAXN],t2[MAXN];void pre() {    int n=5005;    C[0][0]=1;    For(i,n) {        C[i][0]=1;        For(j,i) C[i][j]=add(C[i-1][j-1],C[i-1][j]);    }    t2[0]=1;    For(i,n) t2[i]=mul(t2[i-1],2);}ll pow2(ll a,int b,ll p)  //a^b mod p {      if (a==2&&b<=5000) return t2[b];    if (b==0) return 1%p;      if (b==1) return a%p;      ll c=pow2(a,b/2,p)%p;      c=c*c%p;      if (b&1) c=c*a%p;      return c%p;  }  int c[MAXM]; ll work2(pi *p,int m) {    Rep(i,m) {//      if (p[i].fi<p[i].se) swap(p[i].fi,p[i].se);        if (p[i].se<0) return 0;    }    memset(c,-1,sizeof(c));    Rep(i,m) {        if (c[p[i].fi]==-1 || c[p[i].fi]==p[i].se ) {            c[p[i].fi]=p[i].se;        }  else return 0;    }           m=0;    Rep(i,n+1) if (c[i]^(-1)) p[m++] = mp(i,c[i]); //  sort(p,p+m);//  m=unique(p,p+m)-p;    Rep(i,m-1) {        if (p[i].fi==p[i+1].fi&&p[i].se!=p[i+1].se) return 0;        if (p[i].fi<p[i+1].fi&&p[i].se>p[i+1].se) return 0;    }    ll ans=1;    if (m) ans=C[p[0].fi][p[0].se];    Rep(i,m-1) {        ll a=p[i+1].fi-p[i].fi;        ll b=p[i+1].se-p[i].se;        ans=mul(ans,C[a][b]);    }    ll t=n-p[m-1].fi;    ans=mul(ans,pow2(2,t,F));    return ans; }void work3() {    int mx=0;    Rep(i,m) if (p[i].fi==p[i].se) {        mx=max(mx,p[i].fi);    }    ll ans=0;    Rep(S,n+1) {        int cm=0;        Rep(i,m)            if (p[i].fi<p[i].se) p2[cm++]=mp(n-p[i].se,S-p[i].fi);            else if (p[i].fi>p[i].se) p2[cm++]=p[i];        p2[cm++]=mp(n,S);        memcpy(p3,p2,sizeof(pi)*cm);        p3[cm++]=mp(mx,mx);        upd(ans,work2(p3,cm));        memcpy(p3,p2,sizeof(pi)*(cm-1));        p3[cm-1]=mp(n-mx,S-mx);        upd(ans,work2(p3,cm));        memcpy(p3,p2,sizeof(pi)*(cm-1));        p3[cm-1]=mp(mx,mx);        p3[cm++]=mp(n-mx,S-mx);        ans=sub(ans,work2(p3,cm));        ans=(ans%F+F)%F;    }    cout<<ans<<endl;}int main(){//  freopen("a.in","r",stdin);//  freopen("problem_209/ex_a2.in","r",stdin);//  freopen(".out","w",stdout);    pre();     int T=read();    while(T--) {        n=read();        m=read();        bool fl=0;        Rep(i,m) {            p[i].fi=read(),p[i].se=read();            if (p[i].fi>=p[i].se) fl=1;        }        if (n<=20&&m<=20) work1();        else if (!fl) {            Rep(i,m) swap(p[i].fi,p[i].se);            cout<<work2(p,m)<<endl;        }        else work3();    }    return 0;}
0 0
原创粉丝点击