然后ZUTTER_打的第一场div1以没敢交题 完!美!结!束!!!


A

没有发现性质就找规律海星

我们可以算出一列的贡献:\(g[i][0]\)表示上两个不同,\(g[i][1]\)表示上两个相同就可以互相转移,发现这是0项1项为2的斐波那契数列

有一个发现是如果上一列已经确定了,那么下一列可以和这一列一样或者完全相反其中有在这一列相邻两项都不同的情况下下一列才能与这一列完全相同,且不能有3列完全相同

然后只有2种情况下一列可以完全相同分别编号01也是不能有连续3个数字相同,同上是斐波那契数列

但是直接\(f[n]+f[m]\)还会有01010101和10101010会被算重再减掉2答案就是\(f[n]+f[m]-2\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; int f[400001],n,m;
const int P = 1e9+7;
int main()
{
scanf("%d%d",&n,&m);
f[0]=f[1]=2;
for(int i=2;i<=max(n,m);i++) f[i]=(f[i-1]+f[i-2])%P;
printf("%d",(f[n]+f[m]-2ll+P)%P);
}

B

观察怎样交换会比较优,如果交换并不配对的两个括号必不比交换配对的优

(的值是1,)的值是-1,求前缀和

发现如果已经交换了两个数序列的答案就是序列最小值的出现次数,感性理解一下就是\((....)(...)\)这样互不包含的括号组数

然后就可以做了

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std; const int M = 400001;
int n,m,k,a[M],b[M],d[M],mn=0x3f3f3f3f,w=0,s[3][M],pre[M],S[3],w0,w1,res=-1,pp[M];
char c[M];
stack<int> st;
void check(int x,int W0,int W1)
{
if(x>res) res=x, w0=W0, w1=W1;
} int main()
{
scanf("%d\n%s",&n,c+1);
for(int i=1;i<=n;i++)
{
if(c[i]==')') a[i]=-1;
else a[i]=1;
d[i]=d[i-1]+a[i];
if(d[i]<mn) mn=d[i], w=i+1;
}
if(d[n]!=0)
{
printf("0\n1 1");
return 0;
}
for(int i=w;i<=n;i++)
{
b[++m]=a[i];
pp[m]=i;
}
for(int i=1;i<w;i++)
{
b[++m]=a[i];
pp[m]=i;
}
swap(b,a); for(int i=1;i<=n;i++)
{
s[0][i]=s[0][i-1];
s[1][i]=s[1][i-1];
s[2][i]=s[2][i-1];
d[i]=d[i-1]+a[i];
if(d[i]==0) s[0][i]++;
if(d[i]==1) s[1][i]++;
if(d[i]==2) s[2][i]++;
}
res=s[0][n]; w1=w0=1;
for(int i=1;i<=n;i++)
{
if(a[i]==1) st.push(i);
else pre[i]=st.top(), st.pop();
}
for(int i=1;i<=n;i++)
{
if(!pre[i]) continue;
int p=pre[i];
S[0]=s[0][i-1]-s[0][p-1];
S[1]=s[1][i-1]-s[1][p-1];
S[2]=s[2][i-1]-s[2][p-1];
if(S[0]+S[1]+S[2]==0) continue;
if(!S[0] && !S[1]) check(S[2]+s[0][n],i,p);
else if(!S[0]) check(S[1],i,p);
else check(S[0],i,p);
}
printf("%d\n%d %d",res,min(pp[w0],pp[w1]),max(pp[w0],pp[w1]));
}

C

这题题意好奇怪啊qaq

如果a正在接水,这时\(b(b>a)\)想喝水,他会因为a不在座位上继续坐在座位上等,接着\(c(c<a)\) 又想喝水,他会去排队,所以接水序列acb

如果a正在接水,这时\(b(b<a)\)想喝水,他会去排队,接着\(c(c<a)\) 又想喝水,他也会去排队,所以接水序列abc

抽象一下就是维护一个队列和一个堆。按照想喝水时间和序号排序后如果下一个人的序号比队列里最后一个人还要小也就是说他的前面每个人都在座位上,他会去排队也就是加入队列;否则他会坐在座位上等到他前面的人都回来且正在等着去排队的人也喝完水才能去接水,把他加入堆

每次清空队列后把堆里的第一个人加入队列重复上面过程即可

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std; const int M = 200001;
priority_queue<int> p;
int n,m,k,ct,f[M];
LL rs[M],T;
struct vv
{
int t,id;
} a[M];
bool cmp(vv a,vv b){return (a.t==b.t)?a.id<b.id : a.t<b.t;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].t);
a[i].id=i; f[i]=a[i].t;
}
sort(a+1,a+1+n,cmp);
while(ct<n || p.size())
{
int ir;
if(p.size()) ir=-p.top(), p.pop(), T+=m;
else T=(LL)a[++ct].t+m,ir=a[ct].id;
rs[ir]=T;
while(ct<n && T>=a[ct+1].t)
{
++ct;
if(ir<a[ct].id) p.push(-a[ct].id);
else T+=m, rs[a[ct].id]=T, ir=a[ct].id;
} }
for(int i=1;i<=n;i++) cout<<rs[i]<<' ';
}

D

这题到底是怎么混成div1的D的啊qaqaqaqaq

给定一个n个点的有向图,把n个点分成两组,要求没有第一组指向第二组的边

建一张图和一个反向边的图

如果1在第一组里那么1能连到的点都在第一组,但是如果1能连到整张图那么1就不能再第一组;如果1在第二组那么1在反图中连到的点都在第二组,如果能连满整张图无解

就这样

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm> using namespace std; const int M = 2000001;
int n,m,k,ver[2][M],nex[2][M],head[2][M],cnt,T,x,y,vis[M],ct; void add(int x,int y)
{
ver[0][++cnt]=y, nex[0][cnt]=head[0][x], head[0][x]=cnt;
ver[1][++cnt]=x, nex[1][cnt]=head[1][y], head[1][y]=cnt;
} void dfs(int x,int k)
{
if(vis[x]) return ;
vis[x]=1, ct++;
for(int i=head[k][x];i;i=nex[k][i]) if(!vis[ver[k][i]])dfs(ver[k][i],k);
} int main()
{
scanf("%d",&T);
for(;T;T--)
{
scanf("%d%d",&n,&m); ct=0; cnt=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x!=y)add(x,y);
}
dfs(1,0);
if(ct==n)
{
for(int i=1;i<=n;i++) vis[i]=0;
ct=0;dfs(1,1);
if(ct==n) printf("No\n");
else
{
printf("Yes\n");
printf("%d %d\n",n-ct,ct);
for(int i=1;i<=n;i++) if(!vis[i]) printf("%d ",i);
printf("\n");
for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i);
printf("\n");
}
}
else
{
printf("Yes\n");
printf("%d %d\n",ct,n-ct);
for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i);
printf("\n");
for(int i=1;i<=n;i++) if(!vis[i]) printf("%d ",i);
printf("\n");
}
for(int i=1;i<=n;i++) vis[i]=0;
for(int i=1;i<=cnt;i++) nex[0][i]=nex[1][i]=0;
for(int i=1;i<=n;i++) head[0][i]=head[1][i]=0;
}
}

E

由于左上角和右下角必到,所以分别填最小值和次小值

考虑第一行剩下的值从小到大的填,第二行剩下的值从小到大的填

这样的话就可以保证不会在第1个和第n个位置之外的位置向下走

然后问题就变成把2n-2个数分成两组使差最小,背包即可

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std; const int M = 2000001;
int n,m,k,a[M],S,d[3][M];
LL f[M][26];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n*2;i++) scanf("%d",&a[i]),S+=a[i];
sort(a+1,a+1+n+n); int s=0;
memset(f,-1,sizeof(f));
f[0][0]=0; S-=a[1]+a[2];
S/=2;
for(int i=3;i<=n+n;i++)
{
s+=a[i];
s=min(s,S);
for(int j=s;j>=a[i];j--)
for(int k=min(i-3,(n+n-2)/2);k>=0;k--)
if(f[j-a[i]][k]>=0) f[j][k+1]=f[j-a[i]][k]|(1ll<<i);
}
while(f[S][(n+n-2)/2]==-1) S--;
d[1][1]=a[1];
int ct=1;
LL k=f[S][(n+n-2)/2];
for(int i=3;i<=n+n;i++)
{
if(k&(1ll<<i)) d[1][++ct]=a[i];
}
d[2][n]=a[2];
ct=n;
for(int i=3;i<=n+n;i++)
{
if(!(k&(1ll<<i))) d[2][--ct]=a[i];
}
for(int i=1;i<=n;i++) printf("%d ",d[1][i]);
printf("\n");
for(int i=1;i<=n;i++) printf("%d ",d[2][i]);
}

CF1239的更多相关文章

  1. 在$CF$水题の记录

    CF1158C CF1163E update after CF1173 很好,我!expert!掉rating了!! 成为pupil指日可待== 下次要记得合理安排时间== ps.一道题都没写的\(a ...

随机推荐

  1. python面试题之请谈谈.pyc文件和.py文件的不同之处

    虽然这两种文件均保存字节代码,但.pyc文件是Python文件的编译版本,它有平台无关的字节代码,因此我们可以在任何支持.pyc格式文件的平台上执行它.Python会自动生成它以优化性能(加载时间,而 ...

  2. 【算法】快速数论变换(NTT)初探

    [简介] 快速傅里叶变换(FFT)运用了单位复根的性质减少了运算,但是每个复数系数的实部和虚部是一个余弦和正弦函数,因此系数都是浮点数,而浮点数的运算速度较慢且可能产生误差等精度问题,因此提出了以数论 ...

  3. java虚拟机规范(se8)——class文件格式(六)

    4.7.4 StackMapTable 属性 StackMapTable 属性是一个变长属性,位于 Code(§4.7.3)属性的属性表中.这个属性会在虚拟机类加载的类型阶段(§4.10.1)被使用. ...

  4. Https socket 代理

    https直接与服务器通过ssLsocket连接可行 import java.io.InputStream;import java.io.OutputStream;import java.securi ...

  5. go递归遍历文件目录

    package main import ( "fmt" "io/ioutil" "log" ) //文件目录树形结构节点 type dirT ...

  6. C#设计模式:状态者模式(State Pattern)

    一,什么是状态设计模式? 1,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 2,当一个对象的内部状态改变时允许改变其行为,这个对象看起来像是 ...

  7. Java7中的try-with-resources

    首先,我们看下面的代码. BufferedReader br = null; try { br = new BufferedReader(new FileReader("test.txt&q ...

  8. for循环(C语言型)语法

  9. mongoose 与 mylab 的使用 (1)

    1.引入mongoose  模块 const mongoose = require('mongoose'); 2.连接数据库 //连接数据库 mongoose.connect( db, {useNew ...

  10. linux修改Jvm内存限制

    一.直接通过java 命令去执行class文件的时候,也可以设置JVM参数,eg : java -Xms512m -Xmx1024m HelloWorld在cmd中设置,也必须是执行java命令时 堆 ...