论写5K+的代码在只有样例的条件下都可以调对

由此可见,勇气才是成功的关键

先放题解吧

第一题上午写的暴力不小心忘记题目换根之后还会染色了

然后就挂成了5分QAQ

有很大的部分分是SDOI染色,还有一部分是旅行

但是考试犯懒没有写

很容易发现任何一种颜色在树上都是连续的一段

那么我们不妨这么定义,如果一条边两端颜色不相同,我们定义为虚边,会对子树每个答案产生+1的贡献

如果两端颜色相同,我们定义为实边,不会产生贡献

不难发现,这样定义后的实边和虚边的性质和LCT的定义是一样的

我们考虑使用LCT来维护,每次修改到根的路径就是一个Access

每次Access会使一些实边变成虚边,一些虚边变成实边

很容易在Access的过程中确定这些边,可以发现这些边的数量是等价于LCT复杂度的

也就是单次均摊O(logn),我们对于每次边的变化在对DFS序维护一颗线段树进行子树加减和子树求和就可以了

注意到这里LCT的儿子并不是原树中的儿子,所以我们要对于每个点维护他一直向左走到达的点L

这样修改的目标节点是LCT中的儿子的L,但是由于有换根操作,我们会有rev标记,所以我们还要额外维护一直向右走的点R

我们考虑换根操作,LCT显然可以直接换根

对于我们的线段树,我们可以使用类似于BZOJ 遥远的国度 的讨论方法,可以在不换根的情况下讨论出换根的信息

具体讨论方法就不在多说了,注意如果是菊花树,当根在当前点的子树内的时候,暴力找会挂掉

所以我们对于每个点开vector记录孩子,然后把孩子按DFS序排序,每次二分即可

总时间复杂度O(nlog^2n)

然后ftp挂掉了,没有数据的情况下我居然调了调就A了!撒花~~

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;typedef long long LL;
const int maxn=100010;
int n,m,u,v,rt;
LL ans,sz;
char s[maxn];
int h[maxn],cnt=0;
struct edge{int to,next;
}G[maxn<<1];
int pos[maxn],ed[maxn],tot=0;
vector<int>V[maxn];
LL S[maxn<<2];
int Add[maxn<<2];
int siz[maxn];
bool cmp(const int &x,const int &y){return pos[x]<pos[y];
}
void add(int x,int y){++cnt;G[cnt].to=y;G[cnt].next=h[x];h[x]=cnt;
}
void push_down(int o,int L,int mid,int R){int cl=(o<<1),cr=(o<<1|1);int now=Add[o];Add[o]=0;S[cl]+=now*(mid-L+1);Add[cl]+=now;S[cr]+=now*(R-mid);Add[cr]+=now;
}
void UPD(int o,int L,int R,int x,int y,int v){if(L>=x&&R<=y){S[o]=S[o]+v*(R-L+1);Add[o]+=v;return;}int mid=(L+R)>>1;if(Add[o]!=0)push_down(o,L,mid,R);if(y<=mid)UPD(o<<1,L,mid,x,y,v);else if(x>mid)UPD(o<<1|1,mid+1,R,x,y,v);else {UPD(o<<1,L,mid,x,y,v);UPD(o<<1|1,mid+1,R,x,y,v);}S[o]=S[o<<1]+S[o<<1|1];
}
LL ask(int o,int L,int R,int x,int y){if(L>=x&&R<=y)return S[o];int mid=(L+R)>>1;if(Add[o]!=0)push_down(o,L,mid,R);if(y<=mid)return ask(o<<1,L,mid,x,y);else if(x>mid)return ask(o<<1|1,mid+1,R,x,y);else return ask(o<<1,L,mid,x,y)+ask(o<<1|1,mid+1,R,x,y);
}
int find_pos(int u,int v){int L=0,R=V[u].size()-1;while(L<R){int mid=L+((R-L+1)>>1);int now=V[u][mid];if(pos[v]>=pos[now])L=mid;else R=mid-1;}return V[u][L];
}
void Get_modify(int u,int val){if(u==rt)UPD(1,1,n,1,n,val);else if(pos[rt]<=ed[u]&&pos[rt]>=pos[u]){int v=find_pos(u,rt);UPD(1,1,n,1,n,val);UPD(1,1,n,pos[v],ed[v],-val);}else UPD(1,1,n,pos[u],ed[u],val);
}
LL Get_ans(int u){if(u==rt)return ask(1,1,n,1,n);else if(pos[rt]<=ed[u]&&pos[rt]>=pos[u]){int v=find_pos(u,rt);LL A=ask(1,1,n,1,n);LL B=ask(1,1,n,pos[v],ed[v]);return A-B;}else return ask(1,1,n,pos[u],ed[u]);
}
int Get_sz(int u){if(u==rt)return n;else if(pos[rt]<=ed[u]&&pos[rt]>=pos[u]){int v=find_pos(u,rt);return n-siz[v];}else return siz[u];
}
struct link_cut_tree{int fa[maxn],c[maxn][2];int rev[maxn],L[maxn],R[maxn];#define fa(u) fa[u]#define c(u,i) c[u][i]#define rev(i) rev[i]#define L(i) L[i]bool isroot(int u){return c(fa(u),0)!=u&&c(fa(u),1)!=u;}void pre(int p){if(!isroot(p))pre(fa(p));down(p);}void flip(int u){swap(c(u,0),c(u,1));swap(L[u],R[u]);rev(u)^=1;}void init(){for(int i=1;i<=n;++i)L[i]=i,R[i]=i;}void down(int u){if(rev(u)){if(c(u,0))flip(c(u,0));if(c(u,1))flip(c(u,1));rev(u)=0;}return;}void up(int u){if(c(u,0))L[u]=L[c(u,0)];else L[u]=u;if(c(u,1))R[u]=R[c(u,1)];else R[u]=u;}void rotate(int p,int x){int mark= p==c(x,1),y=c(p,mark^1),z=fa(x);if(c(z,0)==x)c(z,0)=p;if(c(z,1)==x)c(z,1)=p;if(y)fa(y)=x;fa(p)=z;c(p,mark^1)=x;fa(x)=p;c(x,mark)=y;up(x);}void Splay(int p){pre(p);while(!isroot(p)){int x=fa(p),y=fa(x);if(isroot(x))rotate(p,x);else if(p==c(x,0)^x==c(y,0))rotate(p,x),rotate(p,y);else rotate(x,y),rotate(p,x);}up(p);return;}void Access(int u){for(int v=0;u;u=fa(u)){Splay(u);fa(v)=u;if(c(u,1))Get_modify(L[c(u,1)],1);c(u,1)=v;if(v)Get_modify(L[v],-1);v=u;}return;}void make_root(int u){Access(u);Splay(u);flip(u);}
}LCT;void read(int &num){num=0;char ch=getchar();while(ch<'!')ch=getchar();while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
}
void Get_DFS(int u,int f){pos[u]=++tot;siz[u]=1;LCT.fa[u]=f;for(int i=h[u];i;i=G[i].next){int v=G[i].to;if(v==f)continue;V[u].push_back(v);Get_DFS(v,u);siz[u]+=siz[v];}ed[u]=tot;
}int main(){read(n);read(m);for(int i=1;i<n;++i){read(u);read(v);add(u,v);add(v,u);}Get_DFS(1,0);rt=1;LCT.init();for(int i=1;i<=n;++i)sort(V[i].begin(),V[i].end(),cmp);for(int i=1;i<=n;++i)UPD(1,1,n,pos[i],ed[i],1);for(int i=1;i<=m;++i){scanf("%s",s+1);read(u);if(s[3]=='Q'){ans=Get_ans(u);sz=Get_sz(u);printf("%.10lf\n",(double)(ans)/(double)(sz));}else if(s[3]=='L'){LCT.Access(u);}else{//rt=u;LCT.make_root(u);rt=u;}}return 0;
}

第二题很容易发现用组合数算出取哪k个,然后这k个数组成一个置换的方案是(k-1)!,剩余的数就是一个错排函数f

那么就是C(n,k)*(k-1)!*f(n-k)

但是我们发现对于同一个序列,因为它可能有多个k个数组成一个置换的情况,所以我们会算重

然后容斥一下就好了,容斥的式子也是很容易推导的

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std; typedef long long LL;
const int maxn=500010;
const int mod=1e9+7;
int n;
LL jc[maxn],inv[maxn];
LL f[maxn],g[maxn];
LL ans=0; LL pow_mod(LL v,int p){ LL tmp=1; while(p){ if(p&1)tmp=tmp*v%mod; v=v*v%mod;p>>=1; }return tmp;
}
LL C(int n,int m){ return jc[n]*inv[m]%mod*inv[n-m]%mod;
} int main(){ scanf("%d",&n); jc[0]=1; for(int i=1;i<=n;++i)jc[i]=jc[i-1]*i%mod; inv[n]=pow_mod(jc[n],mod-2); for(int i=n-1;i>=0;--i)inv[i]=inv[i+1]*(i+1)%mod; f[0]=1;f[1]=0; for(int i=2;i<=n;++i)f[i]=(f[i-1]+f[i-2])*(i-1)%mod; g[0]=1;g[1]=0;g[2]=1; for(int i=3;i<=n;++i)g[i]=g[i-1]*(i-1)%mod; for(int k=2;k<=n;++k){ int cnt=0; LL tmp=1; for(int j=k;j<=n;j+=k){ cnt++; tmp=tmp*C(n-j+k,k)%mod; tmp=tmp*g[k]%mod; if(cnt&1)ans=ans+tmp*inv[cnt]%mod*f[n-j]%mod; else ans=ans-tmp*inv[cnt]%mod*f[n-j]%mod; if(ans<0)ans+=mod; if(ans>=mod)ans-=mod; } }printf("%lld\n",(ans%mod+mod)%mod); return 0;
}

第三题是个非常丝薄的题目

首先我们搞出这个序列,不难发现题目要求求极长最长上升子序列的个数

由于n<=1000,直接n^2暴力DP就可以了

考试的时候一直在想这个题目是可以O(n)做的啊,后来才发现读入复杂度都是O(n^2)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std; const int maxn=1010;
const int oo=0x7fffffff;
const int mod=1e9+7;
int n,m,u,v;
int deg[maxn];
int a[maxn];
int Num[maxn];
int dp[maxn];
bool vis[maxn][maxn]; void read(int &num){ num=0;char ch=getchar(); while(ch<'!')ch=getchar(); while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
} int main(){ read(n);read(m); for(int i=1;i<=m;++i){ read(u);read(v); if(u>v)swap(u,v); deg[u]++; } for(int i=1;i<=n;++i)Num[i]=i; for(int i=1;i<=n;++i){ int now=deg[i]+1; a[i]=Num[now]; for(int j=now;j<=n;++j)Num[j]=Num[j+1]; } n++;a[0]=0;a[n]=n; for(int i=0;i<=n;++i){ int mn=oo; for(int j=i+1;j<=n;++j){ if(a[j]>a[i]){ if(mn>a[j])vis[i][j]=true; mn=min(mn,a[j]); } } } dp[0]=1; for(int i=1;i<=n;++i){ for(int j=0;j<i;++j){ if(vis[j][i]){ dp[i]+=dp[j]; if(dp[i]>=mod)dp[i]-=mod; } } }printf("%d\n",(dp[n]%mod+mod)%mod); return 0;
}

今天考试比较好的地方:

1、很快的发现第二题的容斥并成功的推出了式子

2、第三题的模型很容易就看了出来

然后就A掉了第二题和第三题

不太好的地方:

1、第一题的花式暴力分懒得去写(导致最后连最简单的暴力都挂掉了,关键是没有用心)

2、第一题想到了维护类似于实边和虚边的东西,但是发现单次可能挂成O(n)就没有往下想

实际上在分析会发现均摊是O(logn)的

需要做的题目:SDOI 旅行

话说天天都坑着一堆题目要做。。

转载于:https://www.cnblogs.com/joyouth/p/5531450.html

5.26 考试修改+总结相关推荐

  1. 2016 10 26考试 NOIP模拟赛 杂题

    Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...

  2. 一级计算机考试修改信息书面申请表,医院信息科修改数据库申请单.doc

    医院信息科修改数据库申请单 医院信息科修改数据库申请单 篇一:医院操作系统及数据库变更申请单 操作系统及数据库变更申请单 ※保持一致.在重装结束后必须到计算机部重新验收,经验收无问题方可重新开通使用. ...

  3. android 修改 dpi_internet搞机(26)修改dpi救砖术[1]

    大家好啊,今天聊一聊前几天的翻车事件吧 前几天为了让手机变得看起来空间更大,就去修改了一下dpi 结果-修改的数值过小,从而导致无限重启(具体就是亮屏了,然后又立马重启到rec), 最后也算是绝望了好 ...

  4. 2013年计算机等级考试修改方案

    2011年7月,我中心组织召开了第五届全国计算机等级考试(NCRE) 考委会会议,会议完成NCRE考委会换届选举,并确定了下一步改革和发展的目标.在新的历史时期,NCRE将以保持稳定为前提.以持续健康 ...

  5. 计算机考试修改照片系统,怎么把照片变成10K的?

    2008-03-29 在个人信息设置栏,我想传个照片上来,按要求压缩成180*120像素,可还是说我的图片大了,是怎么回事呢 你好!如何上传图片1.上传的图片在你的电脑中:进入你的博客→管理博客→发表 ...

  6. mysql--创建表,插入数据,修改表名,删除表,简单查询/内连接、左/右连接

    创建表mm:  其中id为主键且自增长 create table mm(id int(10) primary key not null unique auto_increment,name varch ...

  7. 甘肃省全国计算机等级考试(NCRE)报名

    全国计算机等级考试(National Computer Rank Examination,简称NCRE)是由教育部考试中心主办,面向社会,用于考查应试人员计算机应用知识和能力的全国性计算机水平考试体系 ...

  8. python二级考试怎么报名_计算机二级考试报名流程有哪些

    计算机二级考试报名流程有哪些,计算机二级都考什么,以下是小编整理的计算机二级考试报名流程相关内容,供您参考与阅读. 计算机二级考试报名流程 一.注册通行证 考生登入报名网页后,点击"用户注册 ...

  9. 十堰计算机考试准考证打印

    2019年下半年全国计算机等级考试(十堰考区)将于9月21日-23日举行.报名工作即将开始,现就有关事项公告如下:  一.报名对象 参加全国计算机等级考试不受年龄.职业以及所受教育程度的限制,考生可根 ...

最新文章

  1. Android CoordinatorLayout使用
  2. AR独角兽的死亡教训:融资3亿美元后,成投资人提线木偶,营销大于产品技术...
  3. Ubuntu下bpf纯c程序的编写与运行
  4. 海量数据库解决方案2011031701
  5. mysql 使用表 语句_【mysql】mysql 经常使用建表语句
  6. C语言每日一题之No.9
  7. Django2.2 pymysql 连接mysql数据库的坑
  8. Libra教程之:Libra testnet使用指南
  9. Redis基础(十)——性能监控和监视器
  10. linux下的/dev/shm/ 以及与swap目录的区别
  11. python nmap模块详解_python中的Nmap模块问题
  12. ubuntu-18.10 允许 root登录图形界面
  13. 人工智能-机器学习之seaborn(读取xlsx文件,小提琴图)
  14. Ubuntu GitHub操作——使用仓库
  15. cmmi3认证需要企业具备什么条件?
  16. 基于HFSS的圆极化阵列天线设计
  17. [电脑桌面壁纸]macOS Big Sur 桌面壁纸分享
  18. liang-barsky_C和C ++中的Liang Barsky线裁剪算法
  19. 大数据告诉你:逃离北上广的人最后都去了哪里?
  20. Directadmin清空所有Tickets命令

热门文章

  1. 吃核桃仁有什么好处?
  2. 如果一个人不喜欢争,不喜欢计较,只知道退让,是不是真的傻?
  3. 组织体互联网是个啥?
  4. Qt4_简单的图表编辑器
  5. Liunux 编程遇到的SIGBUS信号
  6. 亚马逊技能开发入门_Amazon QuickSight入门
  7. gdpr合规性测试_使用生产数据在GDPR后世界进行测试
  8. 游标sql server_使用SQL Server游标–优点和缺点
  9. UVa 1639 - Candy(数学期望 + 精度处理)
  10. URL Loading System官方文档翻译一