洛谷11月月赛round.1

太感动了
#2 thwfhk 240 (801ms) 100 100 40

又一张明信片,话说10月的怎么还没收到




P2246 SAC#1 - Hello World(升级版)

题目背景

一天,智障的pipapi正在看某辣鸡讲义学程序设计。

题目描述

在讲义的某一面,他看见了一篇文章。这篇文章由英文字母(大小写均有)、数字、和空白字符(制表/空格/回车)构成。

pipapi想起了他最近刚刚学会写的Hello World程序。他非常好奇,这篇文章中,“HelloWorld”作为子序列到底出现过多少次呢?

由于papapi是个智障,大小写对于他而言毫无区别;因此,“hEllOWorLD”这样的子序列也是可以接受的。O和W之间的空格是也是可以少的;也就是说,“HelloWorld”是可以的。根据标程的意思,就是没有空格,不用考虑空格的情况。

两个子序列相同当且仅当它们每一个字符所在的位置都相同。

由于答案可能很大,请输出结果对1000000007(10^9+7)的余数。

输入输出格式

输入格式:

输入包含若干行。这些行的内容共同构成一篇文章。

文章以EOF(文件结尾)结束。

输出格式:

输出仅包含一个整数,表示这篇文章中“Hello World”出现的次数。

输入输出样例

输入样例#1:

HhEeLlLlOoWwOoRrLlDd

输出样例#1:

1536

输入样例#2:

Gou Li Guo Jia Sheng Si Yi
Qi Yin Huo Fu Bi Qu Zhi
River can feed people
Also can race boats
Hall Ellen Ok Words locked 

输出样例#2:

273

说明

记n为输入的文章的长度(字符数)。

对于20%的数据,n <= 20。

对于50%的数据,n <= 500。

对于所有的数据,15 <= n <= 500000。



直接秒掉,f[i][j]前i个0到j匹配方案数,滚掉第一维

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=5e5+5,MOD=1e9+7;
int n,m,p,mp[300];
char c;
int f[12];

int main(){
    char s[12]="helloworld";
    for(int i=0;i<10;i++) mp[s[i]]=1;

    while((c=getchar())!=EOF){
    if((c>=‘A‘&&c<‘Z‘)||(c>=‘a‘&&c<=‘z‘)){
        if(c<‘a‘) c+=‘a‘-‘A‘;
        if(!mp[c]) continue;
        //printf("%c\n",c);
        if(c==‘h‘) f[1]++;
        else if(c==‘e‘) f[2]+=f[1],f[2]%=MOD;
        else if(c==‘l‘){
            f[4]+=f[3],f[4]%=MOD;
            f[3]+=f[2],f[3]%=MOD;
            f[9]+=f[8],f[9]%=MOD;
        }else if(c==‘o‘){
            f[5]+=f[4],f[5]%=MOD;
            f[7]+=f[6],f[7]%=MOD;
        }else if(c==‘w‘) f[6]+=f[5],f[6]%=MOD;
        else if(c==‘r‘) f[8]+=f[7],f[8]%=MOD;
        else if(c==‘d‘) f[10]+=f[9],f[10]%=MOD;

    }
    }
    printf("%d",f[10]);
}



P2247 SAC#1 - ACOJ云评测计划

题目背景

本题由世界上最蒟蒻最辣鸡最撒比的SOL提供。

寂月城网站是完美信息教室的官网。地址:http://191.101.11.174/mgzd 。

题目描述

ACOJ的服务器简直是差到了一个令人发指的地步。于是SAC的出题人,也就是傻逼SOL,不得不强制要求每一个通过下载ACOJ软件包而搭建的分站,都为主站启动云端评测服务。

云评测服务是由网络来连接的。这样的网络连接是双向的;但是由于地理位置等因素的限制,并不是任意两台服务器都可以直接相连。ACOJ主站已经得到了可以直连的服务器的表,其中包含n个分站(包括主站)以及它们的m条连接情况,可以根据这个来分配各个分站的任务。

有一些分站的服主是SOL的脑残粉。他们会无条件地将他们的服务器提供给SOL。这些ACOJ分站称作“好站”。但是还有一些分站的服主是SOL黑。他们虽然拿到了ACOJ的服务端,但是并不愿意为SOL提供资源,于是利用黑科技关掉了云服务。也就是说,虽然主站仍然认为这些站点存在,但是它们不会起到任何作用——既不能传递通信,也不能进行评测。它们称作“坏站”。

经过千辛万苦的调查,SOL确定了ACOJ云评测系统中有最多k个坏站存在,而且这k个坏站似乎会使得ACOJ的云网络不再联通!大危机!

但是SOL太弱智了,并不能确定是哪k个。于是他请你来帮他找出任意一组可能会使得网络不再联通的k个站点,以便加强防范。

输入输出格式

输入格式:

输入包含m+1行。

第1行3个整数n、m、k。

接下来m行,每行两个整数a、b,表示标号为a和b的站点可以直接相连。

输出格式:

输出包含1行。

不超过k个整数,表示能够将原图割开的任意一组节点组合。

因为使用了Special Judge,所以节点的顺序并不用担心。只需要满足能够割开原图即可。

如果不存在这样的站点集合,输出“How oversuspicious you are, SOL!”;如果网络不存在任何坏站时本来就无法连通,输出“Poor SOL!”。

输入输出样例

输入样例#1:

4 4 2
1 2
2 3
3 4
4 1

输出样例#1:

1 3

输入样例#2:

4 6 2
1 2
2 3
3 4
4 1
1 3
2 4 

输出样例#2:

How oversuspicious you are, SOL!

输入样例#3:

4 0 2

输出样例#3:

Poor SOL!

说明

对于20%的数据,n <= 15。

对于另外20%的数据,n <= 100,k=1。

对于另外20%的数据,n <= 100,k=2。

对于100%的数据,3 <= n <= 500,k <= 3,n-k >= 2,云网络不存在自环和重边。



枚举再求割点

也可以每次重构图

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=505;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
int n,m,k,a,b;
struct edge{
    int v,w,ne;
}e[N*N<<1];
int h[N],cnt=0;
inline void ins(int u,int v){
    cnt++;
    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
    cnt++;
    e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}

int dfn[N],low[N],dfc,scc,iscut[N],cv,nc;
void init(){
	for(int i=0;i<=n;i++) dfn[i]=low[i]=iscut[i]=0;
	dfc=scc=cv=0;
}
void dfs1(int u,int fa){ nc++;
	dfn[u]=low[u]=++dfc;
	int child=0;
	for(int i=h[u];i;i=e[i].ne){
		int v=e[i].v;
		if(!dfn[v]){
			child++;
			dfs1(v,u);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]) iscut[u]=1;
		}else if(v!=fa) low[u]=min(low[u],dfn[v]);
	}
	if(fa==0&&child==1) iscut[u]=0;
	if(iscut[u]) cv=u;
}

void dfs2(int u,int fa,int del){
	dfn[u]=low[u]=++dfc;
	int child=0;
	for(int i=h[u];i;i=e[i].ne){
		int v=e[i].v; if(v==del) continue;
		if(!dfn[v]){
			child++;
			dfs2(v,u,del);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]) iscut[u]=1;
		}else if(v!=fa) low[u]=min(low[u],dfn[v]);
	}
	if(fa==0&&child==1) iscut[u]=0;
	if(iscut[u]) cv=u;
}

void dfs3(int u,int fa,int del1,int del2){
	dfn[u]=low[u]=++dfc;
	int child=0;
	for(int i=h[u];i;i=e[i].ne){
		int v=e[i].v; if(v==del1||v==del2) continue;
		if(!dfn[v]){
			child++;
			dfs3(v,u,del1,del2);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]) iscut[u]=1;
		}else if(v!=fa) low[u]=min(low[u],dfn[v]);
	}
	if(fa==0&&child==1) iscut[u]=0;
	if(iscut[u]) cv=u;
}
int main(){
	n=read();m=read();k=read();
	for(int i=1;i<=m;i++){a=read();b=read();ins(a,b);}

	dfs1(1,0);
	if(nc<n) {puts("Poor SOL!");return 0;}
	else if(cv) {printf("%d",cv);return 0;}

	init();
	if(k==2){
		dfs2(2,0,1);
		if(cv){printf("%d %d",1,cv);return 0;}

		for(int i=2;i<=n;i++){
			init();
			dfs2(1,0,i);
			if(cv){printf("%d %d",i,cv);return 0;}
		}
	}else if(k==3){
		dfs3(3,0,1,2);
		if(cv){printf("%d %d %d",1,2,cv);return 0;}
		for(int i=3;i<=n;i++){
			init();
			dfs3(2,0,1,i);
			if(cv){printf("%d %d %d",1,i,cv);return 0;}
		}
		for(int i=2;i<=n;i++)
			for(int j=i+1;j<=n;j++){
				init();
				dfs3(1,0,i,j);
				if(cv){printf("%d %d %d",i,j,cv);return 0;}
			}
	}
	puts("How oversuspicious you are, SOL!");
	return 0;
}



P2248 分段

题目描述

给定你n个数,要求将它们分成若干连续的段。

要求:

  1. 有m对给定的数不能被分到同一段。
  2. 分出一个段的代价是,其中K和S均为给定的常数,而P则是该段中所有数的最大值,Q是该段中所有数的最小值。
  3. 要求你求出每段代价之和最小的分段方案。

输入输出格式

输入格式:

第一行两个正整数n和m,表示数的个数和不能共存的m对数。

第二行两个非负整数K和S,含义见题面。

第三行n个非负整数,即给定的n个数。

接下来m行每行2个数,表示这两个编号的数不能共存。(编号从1开始)

输出格式:

输出仅一行,表示最小的每段代价之和。

输入输出样例

输入样例#1:

5 2
3 1
2 3 12 14 16
2 3
3 1

输出样例#1:

11

说明

对于10%的数据,

对于30%的数据,

对于另外10%的数据,

对于另外30%的数据,

对于100%的数据,1≤m,n≤100000,0≤K,S,a_i≤100000,1≤pi,qi≤n,pi≠qi。



想了个O(n^2)的DP就打上了,特判了一下S==0,好像没什么用

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const ll INF=1e18;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
int n,m,K,S,a[N],pos[N],p,q;
int mx[N][17],mn[N][17];
void initRMQ(){
    for(int i=1;i<=n;i++) mx[i][0]=mn[i][0]=a[i];

    for(int j=1;j<=16;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]),
            mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
}
int rmq(int l,int r){
    int k=log(r-l+1)/log(2);
    return max(mx[l][k],mx[r-(1<<k)+1][k])-min(mn[l][k],mn[r-(1<<k)+1][k]);
}

ll f[N];
void dp(){
    for(int i=1;i<=n;i++){
        f[i]=INF;int p=pos[i];
        for(int j=i-1;j>=p;j--){
            f[i]=min(f[i],f[j]+K+(ll)S*(ll)rmq(j+1,i));
            p=max(p,pos[j]);
        }
    }
}
struct range{
    int a,b;
    bool operator <(const range &r)const{return b<r.b;}
}d[N];
void sol(){
    int cnt=0;
    for(int i=1;i<=n;i++) if(pos[i]) d[++cnt]=(range){pos[i],i};

    sort(d+1,d+1+cnt);
    int last=0,ans=0;
    for(int i=1;i<=cnt;i++){
        if(d[i].a<=last) continue;
        last=d[i].b;
        ans++;
    }
    printf("%d",ans*K+K);
}

int main(){
    n=read();m=read();K=read();S=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=m;i++){
        p=read();q=read();
        if(p>q) swap(p,q);
        pos[q]=max(pos[q],p);
    }
    if(S==0){
        sol();
    }else{
        initRMQ();
        dp();
        printf("%lld",f[n]);
    }
}
时间: 2024-10-12 20:27:43

洛谷11月月赛round.1的相关文章

洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]

题目描述 萌萌哒的Created equal是一只小仓鼠,小仓鼠自然有仓鼠窝啦. 仓鼠窝是一个由n*m个格子组成的行数为n.列数为m的矩阵.小仓鼠现在想要知道,这个矩阵中有多少个子矩阵!(实际上就是有多少个子长方形嘛.)比如说有一个2*3的矩阵,那么1*1的子矩阵有6个,1*2的子矩阵有4个,1*3的子矩阵有2个,2*1的子矩阵有3个,2*2的子矩阵有2个,2*3的子矩阵有1个,所以子矩阵共有6+4+2+3+2+1=18个. 可是仓鼠窝中有的格子被破坏了.现在小仓鼠想要知道,有多少个内部不含被破

洛谷10月月赛Round.3

Rank11:260=60+100+100 P2409 Y的积木 题目背景 Y是个大建筑师,他总能用最简单的积木拼出最有创意的造型. 题目描述 Y手上有n盒积木,每个积木有个重量.现在他想从每盒积木中拿一块积木,放在一起,这一堆积木的重量为每块积木的重量和.现在他想知道重量和最小的k种取法的重量分别是多少.(只要任意更换一块积木,就视为一种不同的取法.如果多种取法重量总和一样,我们需要输出多次.) 输入输出格式 输入格式: 第一行输入两个整数,n,k,意义如题目所描述. 每组数据接下来的n行,第

洛谷10月月赛Round.1| P3399 丝绸之路 [DP]

题目背景 张骞于公元前138年曾历尽艰险出使过西域.加强了汉朝与西域各国的友好往来.从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他们越过崇山峻岭,将中国的先进技术带向中亚.西亚和欧洲,将那里的香料.良马传进了我国.每当人们凝望荒凉的大漠孤烟,无不引起对往日商贸.文化繁荣的遐想…… 题目描述 小仓鼠带着货物,从中国送到安息,丝绸之路包括起点和终点一共有N+1个城市,0号城市是起点长安,N号城市是终点巴格达.要求不超过M天内必须到达终点.一天的时间可以从一个城市到连续的下一个城市.从i-1城市

洛谷10月月赛Round.1| P3398 仓鼠找sugar[LCA]

题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c)到图书馆(d).他们都会走最短路径.现在小仓鼠希望知道,有没有可能在某个地方,可以碰到他的基友? 小仓鼠那么弱,还要天天被zzq大爷虐,请你快来救救他吧! 输入输出格式 输入格式: 第一行两个正整数n和q,表示这棵树节点的个数和询问的个数. 接下来n-1行,每行两个正整数u和v,表示节点u到节点v之

洛咕11月月赛部分题解 By cellur925

听说是你谷史上最水月赛?我不听我最菜 T1:终于结束的起点 月天歌名好评 给你一个模数 \(M\),请你求出最小的 \(n > 0\),使得\(fib(n)\) \(mod\) \(m=0\),\(fib(n+1)\) \(mod\) \(m=1\). 数学题,开始还想打表验证下,但是我不会告诉你我打表的时候没有很及时地取膜,然后中间有结果溢出,耽误了很长时间,企图找了很久规律.结果发现暴力就能过.hhh. 这个故事告诉我们要及时取膜! #include<cstdio> #include

洛谷-语文成绩-[有奖]洛谷5月月赛:kkksc03的三大神器

题目背景 Background语文考试结束了,成绩还是一如既往地有问题. 题目描述 Description语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行.她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少.你能帮帮她吗? //这又跟神器有什么关系呢?神说:呵呵. //因为n和p的范围比较大 建议C++选手使用scanf读入.//同时建议写读入优化....//最后一个点,亲测pas读入800+ms,c/C++的scanf 1200+ms,所以这个点的时限改为2s 输入输出格式 I

洛谷2017-2月月赛

打CF前随便打打,看了一眼只会做签到题,还挂了一次,95/400. A.富金森林公园 题目大意:给一个长度为n的数列,支持两种操作:1.修改一个数的值:2.给出一个k,问有多少段数大等于k.(N<=200,000) 思路:求出大等k的数的个数减去相邻且都大等k的数字对数就是答案,同时大等两个数必然也大等他们中的较大值,所以用权值线段树分别维护各个数字和相邻的数的最大值就可以了.复杂度O(nlogn).(一开始我写修改时,查他位置上前一个数写成前一个操作位置上的数,挂的惨烈--) #include

洛谷4月月赛R1

T1.题目大意:n个人站成一排,有m个团队,每个人有且属于一个团队,可以让若干个人出队,任意交换这些人的位置后再站回去,问要让所有同一团队的人连续地站在一起,至少要出队几个.(n<=10^5,m<=20) 思路:求至少出队多少个等同于求至多有几个人可以不改变位置.假设我们确定了最后每个团队前面都站了哪些团队,显然每一队所在的区间都是确定的,考虑状压DP,f[i]表示状态为i(状态中表示已经加入了哪些团队)时最小出队人数,枚举一个团队j加入状态,对每个团队做前缀和即可知道该团队在一个区间里有多少

csu-2018年11月月赛Round2-div2题解

csu-2018年11月月赛Round2-div2题解 A(2193):昆虫繁殖 Description 科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强.每对成虫过x个月产y对卵,每对卵要过两个月长成成虫.假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过X个月产卵),问过Z个月以后,共有成虫多少对?0=<X<=20,1<=Y<=20,X=<Z<=50 Input 单组数据 x,y,z的数值 Output 过Z个月以后,共有成虫对