zoukankan      html  css  js  c++  java
  • [考试反思]0308省选模拟40:观察

    今天考试的时候教练在10:30之后把语言从$C++11$改成了$C++$

    并且在$OJ$的比赛界面上写了编译参数。

    然而在$pdf$里浪的我并没有察觉到什么不对。

    嗯。。。你知道我想表达什么。。

    又是蓝色的$0$啊啊啊。。。我估计我是联赛后CE次数最多的了。。

    如果不CE的话会多$22pts$。是$rk3$。

    细节写挂了,特判是树的时候我写的是点数等于边数$-1$。不然是$50pts$,那就是$rk2$了

    然而没有“如果”。缺心眼就是缺心眼,这次长个心眼就是了。

    部分分很足的一次考试。提示意义也挺强。很不错的一套题。

    这次$T1$的思路能想到一部分,但是“从本质上思考”还是差不少的。

    然后$T2$的话猜到可以是生成函数奈何不熟练,而另一个思路完全不可想,拿暴力跑路。

    $T3$是个部分分给的挺明确的网络流,但是连想带写花的时间还是有点多了。

    T1:染色问题

    大意:联通无向图,有$k$种颜色,节点染色,每条边两端颜色不同。求方案数。$n le 10^5,m le n+5,k le 10^5$

    发现$m$比$n$大的不多,而又是联通的,所以离树结构也差不多。

    首先对于小的点,我们可以搜索,当颜色很大时,采用最小表示法就可以了。

    对于一棵树,答案就是$k(k-1)^{n-1}$

    对于一个基环树,如果我们钦定环上某一个点的颜色之后,发现环之外的部分每个点的贡献就是答案乘$k-1$。

    也就是说我们可以不断去掉度数为$1$的点。

    这样只剩下一个环。发现环不好做的原因就是如果你当成序列来做,首尾可能会相同。

    于是我们做$dp$记目前为止链两端颜色是否相同时的方案数。就可以做了。

    然后发现,这样的话你的dp值就已经转移到链上了,只与链的两个端点有关。

    那么一条链就是除了两端以外,度数均为$2$。而我们也可以发现对于一个度数为$2$的点,它两侧点的$dp$值可以合并。

    设$f$为两端相同,$g$为不同,那么有$f=f_0f_1+(k-1)g_0g_1,g=f_0g_1+f_1g_0+(k-2)g_0g_1$

    所以这个点消失,两条边也合并成一条新的边。

    这样,图里也不存在度数为$2$的点了。

    因为$m-n le 5$所以图中度数$geq 3$的点很少,就可以进行搜索了。

    对于三元环,我们最后把它缩成$2$个点会比较好处理。

    支持加边与删边的话,直接用数组复杂度不对,$map/vector$貌似可以用,但是用$set$代码会更好写。

    (不要再想$unordered$啦,关于$C++11$,它死了)

    听$LNC$说可以用$mutable$,好巨啊,代码好写且常数小。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 1000000007
     4 #define S 100005
     5 struct P{
     6     int to,f,g;
     7     P(){} P(int a,int b,int c): to(a),f(b),g(c){}
     8     friend bool operator<(P x,P y){return x.to<y.to||(x.to==y.to&&x.g+x.f<y.g+y.f);}
     9 };multiset<P>s[S];
    10 int n,m,k,rt=1,ans,co[S],A[S],q[S],ald[S],t;
    11 void sch(int al,int alc){
    12     if(al==t+1){
    13         int a=1;
    14         for(int i=1;i<=t;++i)for(set<P>::iterator it=s[q[i]].begin();it!=s[q[i]].end();++it)
    15             if((*it).to>=q[i])a=1ll*a*(co[q[i]]==co[(*it).to]?(*it).f:(*it).g)%mod;
    16         ans=(ans+1ll*a*rt%mod*A[alc])%mod;
    17         return;
    18     }for(int i=1;i<=k&&i<=alc+1;++i)co[q[al]]=i,sch(al+1,max(alc,i));
    19 }
    20 int main(){//freopen("0.in","r",stdin);
    21     cin>>n>>m>>k;
    22     for(int i=A[0]=1;i<=n||i<=k;++i)A[i]=A[i-1]*(k-i+1ll)%mod;
    23     for(int i=1,a,b;i<=m;++i){
    24         scanf("%d%d",&a,&b);
    25         s[a].insert(P(b,0,1));s[b].insert(P(a,0,1));
    26     }
    27     for(int i=1;i<=n;++i)if(s[i].size()==1)q[++t]=i;
    28     for(int h=1,p;p=q[h],h<=t;++h)if(s[p].size()==1){
    29         int u=(*s[p].begin()).to; s[u].erase(s[u].lower_bound(P(p,0,0)));
    30         if(s[u].size()==1)q[++t]=u; ald[p]=1; rt=rt*(k-1ll)%mod;
    31     }
    32     for(int i=1;i<=n;++i)if(s[i].size()==2){
    33         P x=*s[i].begin(),y=*(--s[i].end());
    34         if(x.to==y.to)continue; ald[i]=1;
    35         s[x.to].erase(s[x.to].lower_bound(P(i,0,0)));
    36         s[y.to].erase(s[y.to].lower_bound(P(i,0,0)));
    37         s[x.to].insert(P(y.to,(1ll*x.f*y.f+(k-1ll)*x.g%mod*y.g)%mod,((k-2ll)*x.g%mod*y.g+1ll*x.f*y.g+1ll*x.g*y.f)%mod));
    38         s[y.to].insert(P(x.to,(1ll*x.f*y.f+(k-1ll)*x.g%mod*y.g)%mod,((k-2ll)*x.g%mod*y.g+1ll*x.f*y.g+1ll*x.g*y.f)%mod));
    39     }t=0;
    40     for(int i=1;i<=n;++i)if(!ald[i])q[++t]=i;
    41     sch(1,0);
    42     cout<<ans<<endl;
    43 }
    View Code

    T2:IOer

    大意:给定$n,m,u,v$求$sumlimits_{A}[sumlimits_{x=1}^{m} A_x = n] prodlimits_{x=1}^{m} (v_ui)^{A_i}$。$n le 10^{18},mle  2 imes 10^5,u,v le 10^9$

    好像没啥可说的,题解思路太清奇了。难点就在于这个题意转化。

    好懂不好想。

    很对就是了。粘过来了。

     

     

     也可以用除了$LNC$以外谁都没听明白的生成函数来搞,是大量的推式子。

    几个思路的重点是:将完全相同的元素忽略它们的内部顺序要求,最后除阶乘。

    以及将“分界点”具体化也当成球,类似于插板的思想,这样就能强制它出现。

    其实没什么新东西,但是就是难想到。抖机灵了

    然而代码很好写倒是真

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 998244353
     4 #define S 200005
     5 int qp(int b,long long t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
     6 long long n;int t,m,u,v,fac[S],inv[S],ans;
     7 int main(){
     8     for(int i=fac[0]=1;i<S;++i)fac[i]=1ll*fac[i-1]*i%mod;
     9     inv[S-1]=qp(fac[S-1],mod-2);
    10     for(int i=S-2;~i;--i)inv[i]=inv[i+1]*(i+1ll)%mod;
    11     cin>>t;while(t--){
    12         cin>>n>>m>>u>>v;ans=0;
    13         for(int i=0;i<m;++i)ans=(ans+(i&1?mod-1ll:1ll)*inv[m-1-i]%mod*inv[i]%mod*qp((1ll*(m-i)*u+v)%mod,n+m-1))%mod;
    14         cout<<1ll*ans*qp(u,(m-1ll)*(mod-2))%mod<<endl;
    15     }
    16 }
    View Code

    T3:deadline

    大意:$n$天$m$任务。每个任务有种类$0/1$,有$k$对关系形如:第$u$天可以做第$v$个任务。

    要求你指定一个计划表约定每天要做$0/1$类任务中的哪一种,然后对方会在满足计划表前提下尽可能多做任务。最小化最终完成任务的数量。

    $n,m le 2000,kle 5000$

    一个挺直觉的网络流。最小割。

    所有$0$类任务连源,$1$类任务连汇,然后对于每一天建两个点连$1$边。然后任务向对应的天连边。

    如果一天的边不想被断开,也就是如果这一天不想做任务,那么就要求当天的$0/1$类任务中至少一种被都做完了,也就是割掉了。

    所以是对的。网络流不说复杂度。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 66666
     4 int n,m,k,t[S],o[S][2],pc,q[S],d[S],v[S],fir[S],l[S],to[S],ec=1,ans;
     5 void link(int a,int b,int w){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;v[ec]=w;}
     6 void con(int a,int b){link(a,b,1);link(b,a,0);}
     7 bool bfs(){
     8     for(int i=1;i<=pc;++i)d[i]=pc+1;
     9     for(int h=1,t=1;h<=t;++h)for(int i=fir[q[h]];i;i=l[i])if(v[i]&&d[to[i]]>d[q[h]]+1)
    10         d[q[++t]=to[i]]=d[q[h]]+1;
    11     return d[pc]<=pc;
    12 }
    13 int dfs(int p,int f){
    14     if(p==pc)return f; int r=f;
    15     for(int i=fir[p];i&&r;i=l[i])if(v[i]&&d[to[i]]==d[p]+1){
    16         int x=dfs(to[i],1);
    17         if(!x)d[to[i]]=-1;
    18         else v[i]--,v[i^1]++,r--;
    19     }return f-r;
    20 }
    21 int main(){
    22     scanf("%d%d%d",&n,&m,&k);
    23     pc=n;
    24     for(int i=1;i<=m;++i)o[i][0]=++pc,o[i][1]=++pc,con(pc-1,pc);
    25     ++pc;
    26     for(int i=1;i<=n;++i)scanf("%d",&t[i]);
    27     for(int i=1;i<=n;++i)if(t[i])con(i,pc);else con(0,i);
    28     for(int i=1,x,y;i<=k;++i){
    29         scanf("%d%d",&y,&x);
    30         if(t[y])con(o[x][1],y);
    31         else con(y,o[x][0]);
    32     }
    33     while(bfs())ans+=dfs(0,n);
    34     cout<<ans<<endl;
    35 }
    View Code
  • 相关阅读:
    Quartz 基本概念及原理
    quartz-2.2.x 快速入门 (1)
    hive踩过的小坑
    spring profile 多环境配置管理
    win10窗口设置眼睛保护色
    优雅地在markdown插入图片
    Using Spring Boot without the parent POM
    isDebugEnabled作用
    Log 日志级别
    为什么要使用SLF4J而不是Log4J
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12445180.html
Copyright © 2011-2022 走看看