这个day1稍微有点毒瘤吧??

DAY1

排列

以前总是把day1t1想太复杂了翻车,差不多往正解的方向想了一下感觉不可能这么复杂这可是noipday1t1啊一定有非常简单的方法然后翻车了??

题目转换为求二分图完全匹配数,这个怎么都是十分不好算的,容易想到容斥。

用g[i]表示起码选了i条二分图的补图中的边的匹配数。

那么答案就是

$ans=\sum_{i=0}^{n}g[i]*(n-i)!*(-1)^i$

发现这个二分图的补图长得十分有特点啊。

这是若干条不想交的链构成的图,链与链之间互不影响可以单独考虑。用f[i][j][0/1]表示选到某条链上第i个点,在这条链上选了j条边,第i个点有没有被选的方案数,可以分别dp出每条链。

再跑个背包合并所有链,容斥统计答案即可。这样就有95分啦。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=,p=;
using namespace std;
typedef long long LL;
typedef double db;
int n,K,g[N],f[N][N][],fac[N],up; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int mo(LL x) { return x%p; } #define ANS
int main() {
#ifdef ANS
freopen("permutation.in","r",stdin);
freopen("permutation.out","w",stdout);
#endif
read(n); read(K);
fac[]=;
For(i,,n) fac[i]=(LL)fac[i-]*i%p;
g[]=;
For(cs,,) {
For(i,,K) {
f[i][][]=;
int j=i,tp=;
for(;;) {
if(j+K>n) break;
j+=K; tp++;
For(l,,tp) {
f[j][l+][]=f[j-K][l][];
f[j][l][]=(f[j-K][l][]+f[j-K][l][])%p;
}
}
Rep(l,up,) For(m,,tp)
(g[l+m]+=(LL)g[l]*(f[j][m][]+f[j][m][])%p)%=p;
up+=tp;
}
}
LL ans=;
For(i,,n) {
//printf("%d\n",g[i]);
if(!(i&)) ans=(ans+(LL)g[i]*fac[n-i]%p)%p;
else ans=(ans-(LL)g[i]*fac[n-i]%p+p)%p;
}
printf("%lld\n",ans);
//cerr<<clock()<<endl;
Formylove;
}

95pt

最后5分是什么玩意???

发现这些链其实都一样,只有两种不同长度。又发现刚才的dp其实是一个组合数。就可以直接得到最后要的f,然后多项式exp就可以的答案了。noip之前我不会写这种玩意的。。

苹果树

最简单的一道题,很多人都切了,而且各种方法花样AC。大致有标解的lca,辉神李巨的树剖,ljq的伪tarjan。但是我的随机化应该是最好写的,写得快点大概5min就够了吧。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=;
using namespace std;
typedef unsigned long long LL;
typedef double db;
int n,m; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int ecnt,fir[N],nxt[N<<],to[N<<];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
} map<LL,int>mp,mp2;
LL val[N],val2[N],ans;
void dfs(int x,int fa) {
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
dfs(to[i],x);
val[x]=(val[x]^val[to[i]]);
}
if(fa) {
if(!val[x])
ans+=m;
else if(mp[val[x]])
ans++;
}
} #define ANS
int main() {
#ifdef ANS
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
#endif
srand();
read(n); read(m);
For(i,,n) {
int u,v;
read(u); read(v);
add(u,v);
}
For(i,,m) {
int u,v;
read(u); read(v);
LL t;
t=(((LL)rand()<<)|rand());
while(!t) {
t=(((LL)rand()<<)|rand());
}
mp[t]=;
val[u]^=t;
val[v]^=t;
}
dfs(,);
printf("%llu\n",ans);
//cerr<<clock()<<endl;
Formylove;
}

多项式

披着斗地主外皮的多项式??瑟瑟发抖。

模拟只给50,我大概写模拟都要写3h+把。。。写了个30分的暴力还写挂了,没把不同花色的同种对子区分开。。。

还是noip之前不改系列。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=,p=;
using namespace std;
typedef long long LL;
typedef double db;
int T,n,cnt[N],cc[N],C[][],pr[];
LL ans;
char s[N]; template<typename T>void read(T &x) {
T f=; x=; char ch=getchar();
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void solve1() {
ans=;
For(i,,) cc[i]=;
For(i,,) cc[cnt[i]]++;
if(n==) ans=;
else if(n==) {
if(cc[]==) ans=;
else ans=;
}
else if(n==) {
if(cc[]==) ans=;
else if(cc[]==) ans=;
else ans=;
}
else if(n==) {
ans++; //4 single
if(cc[]==) ans+=; //4:1 3+1:C(4,3) 2+2:3 2+1+1:C(4,2)
if(cc[]==) ans+=; //3+1 3+1 2+1+1:C(3,2)
if(cc[]==) ans++; //2+1
else if(cc[]==) ans+=; //2+2 2+1+1 2+1+1
}
} void dfs2(int pos,int num,int lim) {
if(pos==) {
ans=(ans+num)%p;
return;
}
//if(cnt[pos]==2) dfs2(pos+1,num*2%p,0); // 1+1 or 2
//else dfs2(pos+1,num,0); //
if(cnt[pos]==) dfs2(pos+,num,); for(int j=pos+;cnt[j]&&j<=;j++) { //shun zi
if(j>=pos+&&j>lim) {
int N=num;
For(k,pos,j) {
N=(LL)N*C[cnt[k]][]%p;
cnt[k]--;
}
dfs2(pos,N,j);
For(k,pos,j) cnt[k]++;
}
}
for(int j=pos;cnt[j]==&&j<=;j++) { //lian dui
if(j>=pos+) {
dfs2(j+,num,);
}
}
} #define ANS
int main() {
#ifdef ANS
freopen("polynomial.in","r",stdin);
//freopen("polynomial.out","w",stdout);
#endif
read(T);
For(i,,) C[i][]=;
pr[]=;
For(i,,) pr[i]=pr[i-]*%p;
For(i,,) For(j,,i) C[i][j]=(C[i-][j-]+C[i-][j])%p;
while(T--) {
read(n);
memset(cnt,,sizeof(cnt));
For(i,,n) {
scanf("%s",s);
int len=strlen(s);
if(len==) {
if(s[]=='J') cnt[]++;
else if(s[]=='Q') cnt[]++;
else if(s[]=='K') cnt[]++;
else if(s[]=='A') cnt[]++;
else {
if(s[]-''==) cnt[]++;
else cnt[s[]-'']++;
}
}
else {
if(s[]=='') cnt[]++;
else cnt[]++;
}
}
For(i,,n) scanf("%s",s);
ans=;
if(n<=) solve1();
else dfs2(,,);
printf("%lld\n",ans);
}
//cerr<<clock()<<endl;
Formylove;
}

30pt

DAY2

day2其实并不难,应该是容易AK的,但是DCOI实在太菜了。。

我写t2的时候把线段树的时空复杂度算错了,就想写分块水水,码力太弱(本质是没想清楚),花了太多时间最终却没调出来,只交了暴力,还导致本来很简单的t3根本没时间思考,写了暴力就交。

序列

这种玩意套路的做法就是枚举每个起点i,然后分别统计后面a[j]-(j-i+1)大于0的和小于0的和,前面类似。

也就是每个位置的权值是a[i]-i,每次查询大于或小于某个权值的数的权值和。

树状数组肯定是可以做的,常数优秀一点说不定能过呢。

发现起点一位一位的移时,每次查询的那个数是一点点增大或减小的,而ai又很小,拿cnt数组记一下,每次把刚刚越过线的部分算一算就可以On做了。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=4e6+;
typedef long long LL;
typedef double db;
using namespace std;
LL n,a[N],cnt[N],pos;
LL ans[N],now,sum,sumcnt,nowcnt; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} #define ANS
int main() {
#ifdef ANS
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
read(n);
For(i,,n) read(a[i]);
Rep(i,n,) {
pos=-i;
sum+=a[i]-i; sumcnt++; if(a[i]-i>=pos) now+=a[i]-i,nowcnt++; ans[i]=(now-nowcnt*pos)+((sumcnt-nowcnt)*pos-(sum-now)); cnt[a[i]-i+n]++; now-=pos*cnt[pos+n];
nowcnt-=cnt[pos+n];
} sum=now=sumcnt=nowcnt=;
memset(cnt,,sizeof(cnt));
For(i,,n) {
pos=n-i;
sum+=a[i]-i; sumcnt++;
if(a[i]-i<=pos) now+=a[i]-i,nowcnt++; ans[i+]+=(nowcnt*pos-now)+((sum-now)-(sumcnt-nowcnt)*pos); cnt[a[i]-i+n]++; now-=pos*cnt[pos+n];
nowcnt-=cnt[pos+n];
} LL rs=ans[];
For(i,,n) rs=min(rs,ans[i]);
printf("%lld\n",rs);
Formylove;
}

迷宫

线段树时空复杂度都怎么算怎么ok啊,而且超级好写的啊。。

就是有点卡常,我要加register才能卡过最后两个点。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(register int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
#define Formylove return 0
#define inf 1e8
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,q,a[][N]; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void GM(int &x,int y) { if(x>y) x=y; } #define lc x<<1
#define rc ((x<<1)|1)
#define mid ((l+r)>>1)
int sg[N<<][][];
void upd(int x,int l,int r) {
memset(sg[x],/,sizeof(sg[x]));
if(l==r) {
For(i,,n) if(a[i][l]) sg[x][i][i]=;
For(i,,n) Rep(j,i-,) if(a[i][l]&&a[i-][l]) {
GM(sg[x][i][j],sg[x][i-][j]+);
GM(sg[x][j][i],sg[x][i-][j]+);
}
}
else {
For(i,,n) For(j,,n) {
For(k,,n) if(a[k][mid]&&a[k][mid+])
GM(sg[x][i][j],sg[lc][i][k]+sg[rc][k][j]+);
}
}
} void build(int x,int l,int r) {
if(l==r) { upd(x,l,r); return; }
build(lc,l,mid); build(rc,mid+,r);
upd(x,l,r);
} void update(int x,int l,int r,int p1,int p2) {
if(l==r) {
a[p2][p1]^=;
upd(x,l,r); return;
}
if(p1<=mid) update(lc,l,mid,p1,p2);
else update(rc,mid+,r,p1,p2);
upd(x,l,r);
} int tp[][],rs[][],ok;
void merge(int x,int l,int r) {
if(!ok) {
ok=;
For(i,,n) For(j,,n)
tp[i][j]=sg[x][i][j];
}
else {
memset(rs,/,sizeof(rs));
For(i,,n) For(j,,n) {
For(k,,n) if(a[k][l-]&&a[k][l])
GM(rs[i][j],tp[i][k]+sg[x][k][j]+);
}
memcpy(tp,rs,sizeof(rs));
}
} void qry(int x,int l,int r,int ql,int qr) {
if(l>=ql&&r<=qr) { merge(x,l,r); return; }
if(ql<=mid) qry(lc,l,mid,ql,qr);
if(qr>mid) qry(rc,mid+,r,ql,qr);
} #define ANS
int main() {
#ifdef ANS
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
#endif
read(n); read(m); read(q);
For(i,,n) For(j,,m) read(a[i][j]);
build(,,m);
For(cs,,q) {
int o,x,y,z,w;
read(o); read(x); read(y);
if(o==)
update(,,m,y,x);
else {
read(z); read(w);
ok=;
qry(,,m,y,w);
if(tp[x][z]>=inf) puts("-1");
else printf("%d\n",tp[x][z]);
}
}
Formylove;
}

动态数点

从n^2暴力优化到标解蛮容易的,二分长度,st表处理gcd和min值。只是似乎又要卡常了。

看李巨一个排序的复杂度爆踩std。

按a从小到大排序,然后拓展。拓展过的点就不用再拓展了,发现每个点最多被拓展两边,左边一遍右边一遍(3 15 5)。

辉神就更强了,从左到右依次拓展但是每次拓展的中心是上一次拓展的右边界的下一个,这样最坏的情况下也只能卡成nlogv的,而实际远不到上限,跑得飞快。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
int n,b[N],vis[N],a[N];
int tot,ans; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int pos,a;
friend bool operator <(const node&A,const node&B) {
return A.a<B.a;
}
}p[N]; #define ANS
int main() {
#ifdef ANS
freopen("point.in","r",stdin);
freopen("point.out","w",stdout);
#endif
read(n);
For(i,,n) {
read(a[i]);
p[i].a=a[i];
p[i].pos=i;
}
sort(p+,p+n+);
For(i,,n) {
int l=p[i].pos,r=p[i].pos;
if(vis[l]) continue;
while(l>&&a[l-]>=p[i].a&&a[l-]%p[i].a==)
vis[--l]=;
while(r<n&&a[r+]>=p[i].a&&a[r+]%p[i].a==)
vis[++r]=;
b[l]=r-l;
ans=max(ans,r-l);
}
For(i,,n) tot+=(b[i]==ans);
printf("%d %d\n",tot,ans);
For(i,,n) if(b[i]==ans) printf("%d ",i);
puts("");
Formylove;
}

李巨做法的代码

最新文章

  1. SVN中(trunk tags branches)的使用理解
  2. Raspberry Pi 3 Basic Command and Information
  3. 10. javacript高级程序设计-DOM
  4. Html 字体大小单位 px em pt
  5. Arch xfce4 安装解压缩软件
  6. jbpm3.2中jbpm.jpdl.mysql.sql文件运行报错的问题
  7. 有关sybase的一些零星经验
  8. 使用OpenFileDialog实现图片上传
  9. centos系统安装中文字体几种方法
  10. (转)Jquery获取上级、下级或者同级的元素
  11. Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题
  12. MySQL经典编程问题
  13. Red Hat 6.3安装gcc gc++
  14. js 动画效果实现
  15. BAT面试的准备—iOS篇
  16. VB6 MsgBox 函数
  17. 即时通信系统Openfire分析之三:ConnectionManager 连接管理
  18. luoguP4555 [国家集训队]最长双回文串 manacher算法
  19. 使用HTML5画饼图
  20. 防止网页被别站用 iframe嵌套

热门文章

  1. TCP协议解析及相关问题
  2. HBase封装easy-hbase设计实现
  3. Jenkins应用
  4. SQL Select选择
  5. Android中的ListView的绘制过程中执行的方法
  6. C语言新手写扫雷源代码
  7. php开发面试题---php高级程序员需要掌握的一些知识
  8. js检查判断设备
  9. java lambda filter写法
  10. 根据已知值,选中selec中的选项