然后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. 51-python基础-python3-列表-常用列表方法- index()方法

    index()方法 1-可以传入一个值,如果该值存在于列表中,就返回它的下标. 实例1: 2-如果该值不在列表中,Python 就报 ValueError. 实例2: 3-如果列表中存在重复的值,就返 ...

  2. 一些常ArcGIS常用简单算法 C#

    最近开始重构不顺眼的辣鸡代码,顺带将某个模块的一个算法辅助类贴到这里. /// <summary> /// 算法逻辑辅助类 /// </summary> internal st ...

  3. 删除文件时提示“找不到该项目”,怎么解决? 转摘自:http://jingyan.baidu.com/article/e4d08ffdf5ab470fd2f60df4.html

    故障现象:在使用Windows系统删除文件或者文件夹的时候,有时会出现“找不到该项目”的错误提示,可能再次“重试”也无济于事. 那么,接下来T库小编就为库友们简单概括一下出现该问题的原因. 故障原因: ...

  4. element UI的使用

    npm install --save element-ui main.js里面添加 import ElementUI from 'element-ui' import 'element-ui/lib/ ...

  5. 简易的富文本编辑器WangEditor

    网址http://www.wangeditor.com/ var E = window.wangEditor; var editor = new E('#editor') // 或者 var edit ...

  6. 使用while循环实现菜单

  7. 力扣——single number (只出现一次的数字) python实现

    题目描述: 中文: 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 英 ...

  8. 【vlfeat】O(n)排序算法——计数排序

    今天想在网上找一个实现好的er算法来着,没啥具体的资料,无奈只能看vlfeat的mser源码,看能不能修修补补实现个er. 于是,看到某一段感觉很神奇,于是放下写代码,跑来写博客,也就是这段 /* - ...

  9. git小乌龟图标不显示 windows系统

    1.修改注册表[windows + R 输入 regedit]进入注册信息,按照步骤找到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre ...

  10. sql格式化时间

    sql格式化date类型 DATE_FORMAT(nuw(), '%Y-%m-%d') sql格式化long类型时间 FROM_UNIXTIME(time/1000,'%Y-%m-%d')