zoukankan      html  css  js  c++  java
  • 20180702小测

    这场考试我其实并没有参加......
    因为一些奥妙重重的原因肚子疼到厌生,没看完题就滚回家了......
    马上就NOI了还是这种身体状态,真是要完。

    T1:


    我们先把所有点双联通分量缩起来。
    如果这个双联通分量只有一条边,那么方案数显然是k;
    如果这个双联通分量恰好是一个环,那么方案数可以用polya定理计算;
    否则,这个双联通分量的任意两条边可以互换颜色(自行构造一下就知道了),所以方案数只和某种颜色出现几次有关,大力插板即可。
    双联通分量的形态怎么判?记录点数和边数判断即可。
    具体就是用vector存下来每个分量的每条边,然后暴力数点即可。
    (这里吐槽一句求点双联通分量栈里面压点的都是邪教!你那么做根本没法统计返祖边!)
    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<cctype>
      7 #define debug cout
      8 typedef long long int lli;
      9 using namespace std;
     10 const int maxn=5e5+1e2,maxe=1e6+1e2;
     11 const int mod=1e9+7;
     12 
     13 int inv[maxe];
     14 inline int mul(const int &x,const int &y) {
     15     return (lli) x * y % mod;
     16 }
     17 inline void adde(int &dst,const int &x) {
     18     if( ( dst += x ) >= mod ) dst -= mod;
     19 }
     20 inline void mule(int &dst,const int &x) {
     21     dst = (lli) dst * x % mod;
     22 }
     23 inline int fastpow(int base,int tim) {
     24     int ret = 1;
     25     while(tim) {
     26         if( tim & 1 ) mule(ret,base);
     27         if( tim >>= 1 ) mule(base,base);
     28     }
     29     return ret;
     30 }
     31 inline int c(int x,int y) {
     32     int ret = 1;
     33     for(int i=0;i<y;i++) mule(ret,x-i);
     34     for(int i=1;i<=y;i++) mule(ret,inv[i]);
     35     return ret;
     36 }
     37 inline int gcd(int x,int y) {
     38     register int t;
     39     while( t = x % y ) x = y , y = t;
     40     return y;
     41 }
     42 
     43 int u[maxe],v[maxe];
     44 int s[maxn],t[maxe<<1],nxt[maxe<<1];
     45 int dfn[maxn],low[maxn],stk[maxe],top,fs;
     46 vector<int> es[maxn<<1];
     47 bool vis[maxn];
     48 int n,m,k,ans=1;
     49 
     50 inline void coredge(int from,int to) {
     51     static int cnt = 1;
     52     t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     53 }
     54 inline void addedge(int a,int b) {
     55     coredge(a,b) , coredge(b,a);
     56 }
     57 inline void dfs(int pos,int sou) {
     58     static int dd; low[pos] = dfn[pos] = ++dd , vis[pos] = 1;
     59     for(int at=s[pos];at;at=nxt[at]) if( at != ( sou ^ 1 ) ) {
     60         if( !vis[t[at]] ) {
     61             stk[++top] = at;
     62             dfs(t[at],at) , low[pos] = min( low[pos] , low[t[at]] );
     63             if( low[t[at]] >= dfn[pos] ) {
     64                 int x; ++fs;
     65                 do es[fs].push_back((x=stk[top--])>>1); while( x != at );
     66             }
     67         } else {
     68             if( dfn[t[at]] < dfn[pos] ) stk[++top] = at;
     69             low[pos] = min( low[pos] , dfn[t[at]] );
     70         }
     71     }
     72 }
     73 inline void calc_ring(const vector<int> &vec) {
     74     if( vec.size() == 1 ) return mule(ans,k);
     75     int ps = 0;
     76     for(unsigned i=0;i<vec.size();i++) {
     77         if( !vis[u[vec[i]]] ) ps += vis[u[vec[i]]] = 1;
     78         if( !vis[v[vec[i]]] ) ps += vis[v[vec[i]]] = 1;
     79     }
     80     for(unsigned i=0;i<vec.size();i++) vis[u[vec[i]]] = vis[v[vec[i]]] = 0;
     81     if( ps == (signed)vec.size() ) {
     82         int ret = 0;
     83         for(int i=1;i<=ps;i++) adde(ret,fastpow(k,gcd(i,ps)));
     84         mule(ret,inv[ps]) , mule(ans,ret);
     85     } else mule(ans,c(k+vec.size()-1,vec.size()));
     86 }
     87 
     88 inline void init() {
     89     inv[0] = inv[1] = 1;
     90     for(int i=2;i<=m;i++) inv[i] = mul(mod-mod/i,inv[mod%i]);
     91 }
     92 
     93 inline int getint() {
     94     int ret = 0 , ch;
     95     while( !isdigit(ch=getchar()) );
     96     do ret = ret * 10 + ch - '0'; while( isdigit(ch=getchar()) );
     97     return ret;
     98 }
     99 
    100 int main() {
    101     n = getint() , m = getint() , k = getint() , init();
    102     for(int i=1;i<=m;i++) addedge(u[i]=getint(),v[i]=getint());
    103     for(int i=1;i<=n;i++) if( !vis[i] ) dfs(i,0);
    104     memset(vis,0,sizeof(vis));
    105     for(int i=1;i<=fs;i++) calc_ring(es[i]);
    106     printf("%d
    ",ans);
    107     return 0;
    108 }
    View Code



    T2:


    我会有下界的最小流!
    等等,为什么要按照上下界建图呢?直接从钦定边全选的状态开始退流就行了,限制每个点能退的流量。水题!
    然而SPJ还得自己改......
    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cctype>
     7 #define debug cout
     8 using namespace std;
     9 const int maxn=4e3+1e2,maxe=8e3+1e2;
    10 const int inf=0x3f3f3f3f;
    11 
    12 int u[maxn],v[maxn],deg[maxn];
    13 int n1,n2,m,mi=inf;
    14 
    15 namespace NetworkFlow {
    16     int s[maxn],t[maxe],nxt[maxe],f[maxe],cnt;
    17     int dep[maxn],st,ed;
    18     inline void coredge(int from,int to,int flow) {
    19         t[++cnt] = to , f[cnt] = flow , nxt[cnt] = s[from] , s[from] = cnt;
    20     }
    21     inline void singledge(int from,int to,int flow) {
    22         coredge(from,to,flow) , coredge(to,from,0);
    23     }
    24     inline bool bfs() {
    25         memset(dep,-1,sizeof(dep)) , dep[st] = 0;
    26         queue<int> q; q.push(st);
    27         while( q.size() ) {
    28             const int pos = q.front(); q.pop();
    29             for(int at=s[pos];at;at=nxt[at]) if( f[at] && !~dep[t[at]] ) {
    30                 dep[t[at]] = dep[pos] + 1 , q.push(t[at]);
    31             }
    32         }
    33         return ~dep[ed];
    34     }
    35     inline int dfs(int pos,int flow) {
    36         if( pos == ed ) return flow;
    37         int ret = 0 , now = 0;
    38         for(int at=s[pos];at;at=nxt[at]) if( f[at] && dep[t[at]] > dep[pos] ) {
    39             now = dfs(t[at],min(flow,f[at])) , ret += now , flow -= now , f[at] -= now , f[at^1] +=  now;
    40             if( !flow ) return ret;
    41         }
    42         if( !ret ) dep[pos] = -1;
    43         return ret;
    44     }
    45     inline int dinic() {
    46         int ret = 0;
    47         while( bfs() ) ret += dfs(st,inf);
    48         return ret;
    49     }
    50     inline void reset() {
    51         memset(s,0,sizeof(s)) , cnt = 1;
    52     }
    53 }
    54 
    55 inline void build(int k) {
    56     NetworkFlow::reset() , NetworkFlow::st = n1 + n2 + 1 , NetworkFlow::ed = n1 + n2 + 2;
    57     for(int i=1;i<=m;i++) NetworkFlow::singledge(n1+v[i],u[i],1);
    58     for(int i=1;i<=n1;i++) NetworkFlow::singledge(i,NetworkFlow::ed,deg[i]-k);
    59     for(int i=n1+1;i<=n1+n2;i++) NetworkFlow::singledge(NetworkFlow::st,i,deg[i]-k);
    60 }
    61 inline void printans() {
    62     static int seq[maxn],sql; sql = 0;
    63     using namespace NetworkFlow; dinic();
    64     for(int i=1;i<=m;i++) if( f[i<<1] ) seq[++sql] = i;
    65     sort(seq+1,seq+1+sql) , printf("%d ",sql);
    66     for(int i=1;i<=sql;i++) printf("%d ",seq[i]);
    67     putchar('
    ');
    68 }
    69 
    70 inline int getint() {
    71     int ret = 0 , ch;
    72     while( !isdigit(ch=getchar()) );
    73     do ret = ret * 10 + ch - '0'; while( isdigit(ch=getchar()) );
    74     return ret;
    75 }
    76 
    77 int main() {
    78     n1 = getint() , n2 = getint() , m = getint();
    79     for(int i=1;i<=m;i++) ++deg[u[i]=getint()] , ++deg[n1+(v[i]=getint())];
    80     for(int i=1;i<=n1+n2;i++) mi = min( mi , deg[i] );
    81     for(int i=0;i<=mi;i++) build(i) , printans();
    82     return 0;
    83 }
    View Code

    SPJ:

     1 #include<cstdio>
     2 #define WA return puts("0"),0
     3 #define AC return puts("4"),0
     4 int n1,n2,m,u[2010],v[2010],md,ans[2010],deg[2][2010];
     5 bool used[2010];
     6 int full;
     7 int main(int argc,char*argv[]){
     8     freopen(argv[1],"r",stdin);
     9     scanf("%d%d%d",&n1,&n2,&m);
    10     for(int i=0;i<m;i++)scanf("%d%d",u+i,v+i);
    11     freopen(argv[3],"r",stdin);
    12     md=-1;
    13     while(scanf("%d",ans+(++md))==1){
    14         for(int i=ans[md];i--;)scanf("%*d");
    15     }
    16     md--;
    17     freopen(argv[2],"r",stdin);
    18     freopen(argv[5],"w",stdout);
    19     for(int i=0;i<=md;i++){
    20         int c;
    21         if(scanf("%d",&c)!=1||c!=ans[i])WA;
    22         for(int j=0;j<m;j++)used[j]=0;
    23         for(int j=0;j<n1;j++)deg[0][j]=0;
    24         for(int j=0;j<n2;j++)deg[1][j]=0;
    25         while(c--){
    26             int x;
    27             if(scanf("%d",&x)!=1||x<1||x>m||used[x-1])WA;
    28             used[--x]=1;
    29             deg[0][u[x]]++;
    30             deg[1][v[x]]++;
    31         }
    32         for(int j=1;j<=n1;j++)if(deg[0][j]<i)WA;
    33         for(int j=1;j<=n2;j++)if(deg[1][j]<i)WA;
    34     }
    35     AC;
    36 }
    View Code


    T3:


    一脸不可做的样子......
    考虑对每个点统计覆盖它的圆的贡献。
    我们先计算第一象限(含x轴)的答案,最后乘4在加上原点的贡献即可。
    考虑枚举点的坐标,我们有:

    (后面j是在枚举能覆盖这个点的圆,后面乘的是这个圆被统计的次数)
    我们令:

    显然关于x的k次多项式的前缀和或有上界的后缀和都是一个关于x的k+1次多项式。所以这个s我们能拉格朗日插值。
    那么我们的公式能化为:

    我们令:

    就是一个把x当做常数,关于y的函数了。
    我们理性分析一下,S(x)是关于x的3次多项式,那么S(x^2+y^2)就是关于y的6次多项式,而这个东西是S(x^2+y^2)的前缀和,就是关于y的7次多项式喽。
    于是我们又能大力拉格朗日插值......
    然后我们枚举x,这题就做完了......复杂度O(sqrt(m)),常数巨大,最后一个点要7s......
    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define debug cout
     7 typedef long long int lli;
     8 using namespace std;
     9 const int mod=1e9+7;
    10 
    11 inline int add(const int &x,const int &y) {
    12     const int ret = x + y;
    13     return ret >= mod ? ret - mod : ret;
    14 }
    15 inline int sub(const int &x,const int &y) {
    16     const int ret = x - y;
    17     return ret < 0 ? ret + mod : ret;
    18 }
    19 inline int mul(const int &x,const int &y) {
    20     return (lli) x * y % mod;
    21 }
    22 inline void adde(int &dst,const int &x) {
    23     if( ( dst += x ) >= mod ) dst -= mod;
    24 }
    25 inline void sube(int &dst,const int &x) {
    26     if( ( dst -= x ) < 0 ) dst += mod;
    27 }
    28 inline void mule(int &dst,const int &x) {
    29     dst = (lli) dst * x % mod;
    30 }
    31 inline int fastpow(int base,int tim) {
    32     int ret = 1;
    33     while(tim) {
    34         if( tim & 1 ) mule(ret,base);
    35         if( tim >>= 1 ) mule(base,base);
    36     }
    37     return ret;
    38 }
    39 
    40 struct Interval {
    41     int xs[11],ys[11],ps[11],cnt;
    42     inline void insert(const int &x,const int &y) {
    43         xs[++cnt] = x , ys[cnt] = y;
    44     }
    45     inline void init() {
    46         for(int i=1;i<=cnt;i++) {
    47             ps[i] = 1;
    48             for(int j=1;j<=cnt;j++) if( j != i ) mule(ps[i],sub(xs[i],xs[j]));
    49             ps[i] = fastpow(ps[i],mod-2);
    50         }
    51     }
    52     inline int calc(const int &x) {
    53         int ret = 0;
    54         for(int i=1;i<=cnt;i++) {
    55             int pi = 1;
    56             for(int j=1;j<=cnt;j++) if( j != i ) mule(pi,sub(x,xs[j]));
    57             adde(ret,mul(mul(pi,ps[i]),ys[i]));
    58         }
    59         return ret;
    60     }
    61     inline void reset() {
    62         cnt = 0;
    63     }
    64 }s,f;
    65 
    66 lli m;
    67 int sq,ans;
    68 
    69 inline void inits() {
    70     const int m = ::m % mod;
    71     for(int i=m,su;i>m-4;i--) {
    72         su = 0;
    73         for(int j=i;j<=m;j++) adde(su,mul(j,sub((m+1)%mod,j)));
    74         s.insert(i,su);
    75     }
    76     s.init();
    77 }
    78 inline void initf(int x) {
    79     f.reset();
    80     for(int i=1,su=0;i<=8;i++) adde(su,s.calc(((lli)x*x+i*i)%mod)) , f.insert(i,su);
    81     f.init();
    82 }
    83 
    84 int main() {
    85     scanf("%lld",&m) , inits() , sq = sqrt(m);
    86     for(int i=0;i<=sq;i++) {
    87         if( (lli) i * i + 8 * 8 <= m ) initf(i) , adde(ans,f.calc((lli)sqrt(m-(lli)i*i)%mod));
    88         else {
    89             int t = sqrt(m-(lli)i*i);
    90             for(int j=1;j<=t;j++) adde(ans,s.calc(((lli)i*i+j*j)%mod));
    91         }
    92     }
    93     mule(ans,4) , adde(ans,s.calc(0)) , printf("%d
    ",ans);
    94     return 0;
    95 }
    View Code



    夜(よる)が明(あ)けて朝(あさ)が来(く)る
    黑夜终去 黎明终来
    星空(ほしぞら)が朝(あさ)に溶(と)けても
    繁星即使融化于晨
    君(きみ)の辉(かがや)きはわかるよ
    我依可见君之光辉
    思(おも)い出(で)を羽(は)ばたかせ
    思念化为羽翼
    君(きみ)の空(そら)へ舞(ま)い上(あ)がる
    飞向星之所在

  • 相关阅读:
    5月27日
    5月26日
    5月25日
    5月24日
    5月22日
    梦断代码(3)
    01团队冲刺
    07周总结
    06周总结
    构建之法阅读笔记
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/9255674.html
Copyright © 2011-2022 走看看