浙工大新生赛莫队处理+区间DP+KMP+分析题
题目描述
输入描述:
第一行一个整数T,表示有T组数据。
对于每组数据,
接下来q行,每行输入2个整数 l, r
输出描述:
对于每一个询问,输出满足条件的二元组(l
2
,r
2
)的数目。
输入例子:
1
5 2 4
4 1 4 8 8
2 2
2 4
输出例子:
0
3
-->
输入
1
5 2 4
4 1 4 8 8
2 2
2 4
输出
0
3
说明
备注:
他r假设要向右移动的时候,那么先把r向右移动一格,++r,然后ANS再加cnt[A[r]],然后再让cnr[A[r]]++。就是现有满足条件可以还原成这样for(int i=l;i<r;++i) ANS+=(a[i]==a[r]),如果a[i]==a[r],说明的是i+1到r这个区间的总和满足对k取余为0(注意这是一个闭区间,同时注意到最小区间左端点是l+1,维护了左开),然后观察就知道如果他本身是的话,就相当于a[r-1]==a[r]就行了(右闭满足),如果先加cnt[a[r]],那就重复计数计多了。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+;
int block;
struct node{
int id,l,r;
bool operator<(const node &A)const{
return (l-)/block==(A.l-)/block?r<A.r:l<A.l;
}
}Q[N];
int A[N],B[N],cnt[N],ans[N];
int main(){
int n,m,k,T;
for(scanf("%d",&T);T--;){
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;++i) {
scanf("%d",A+i);
A[i]=(A[i]+A[i-])%k;
B[i]=A[i];
}
block=(int)sqrt(n);
B[n+]=;
sort(B+,B+n+);
int tot=unique(B+,B+n+)-B-;
for(int i=;i<=n;++i) A[i]=lower_bound(B+,B+tot+,A[i])-B-,cnt[i]=;
for(int i=;i<=m;++i) scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].id=i;
sort(Q+,Q+m+);
int l=Q[].l,r=Q[].l-,ANS=;
for(int i=;i<=m;++i) {
while(l<Q[i].l) --cnt[A[l]],ANS-=cnt[A[l++]];
while(l>Q[i].l) ANS+=cnt[A[--l]],++cnt[A[l]];
while(r>Q[i].r) --cnt[A[r]],ANS-=cnt[A[r--]];
while(r<Q[i].r) ANS+=cnt[A[++r]],++cnt[A[r]];
ans[Q[i].id]=ANS+cnt[A[l-]];
}
for(int i=;i<=m;++i) printf("%d\n",ans[i]);
}
}
题目描述
输入描述:
第一行表示主机数n。
接下来有n行,第i(i=0,1,2,⋯,n−1)行有两个数a,b,表示主机i和主机a,主机i和主机b各有网线相连。
输入有多组数据,n=0时,表示输入结束,请不要有对该组数据任何输出。
输出描述:
每组数据输出一行,表示方案数对1000,000,007取模的结果。(行末不要有多余的空白字符)
输入例子:
5
2 3
4 4
0 3
0 2
1 1
12
11 11
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
0 0
2
1 1
0 0
0
输出例子:
6
3840
0
-->
输入
5
2 3
4 4
0 3
0 2
1 1
12
11 11
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
0 0
2
1 1
0 0
0
输出
6
3840
0
备注:
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+;
const int mod=1e9+;
int fa[N],size[N];
int findx(int x) {
return x==fa[x]?x:(fa[x]=findx(fa[x]));
}
int main(){
int n,x,y;
while(scanf("%d",&n),n){
int m=n;
for(int i=;i<=n;++i) fa[i]=i,size[i]=;
for(int i=;i<n;++i) {
for(int j=;j<;++j){
scanf("%d",&x);
int ux=findx(x),uz=findx(i);
if(uz!=ux) {
fa[ux]=uz;
size[uz]+=size[ux];
--m;
}
}
}
if(m==) puts("");
else {
int ans=;
for(int i=;i<m;++i) ans=(1LL*ans*i*)%mod;
for(int i=;i<n;++i) if(fa[i]==i) ans=(1LL*ans*(1LL*size[i]*(size[i]-)/%mod))%mod;//括号要括好
printf("%d\n",ans);
}
}
}
给定两个长度为n的整数列A和B,每次你可以从A数列的左端或右端取走一个数。假设第i次取走的数为ax,则第i次取走的数的价值vi=bi⋅ax,现在希望你求出∑vi的最大值。
输入描述:
第一行一个数T,表示有T组数据。
对于每组数据,第一行一个整数n,
接下来两行分别给出A数列与B数列。
输出描述:
每一组数据输出一行,最大的∑v
i
。
输入例子:
2
2
1 1000
2 1
5
1 3 5 2 4
1 2 3 4 5
输出例子:
2001
52
-->
输入
2
2
1 1000
2 1
5
1 3 5 2 4
1 2 3 4 5
输出
2001
52
说明
对于第二个样例,
第一次从左边取走a1,v1=a1⋅b1=1,
第二次从左边取走a2,v2=a2⋅b2=6,
第三次从右边取走a5,v3=a5⋅b3=12,
第四次从右边取走a4,v4=a4⋅b4=8,
第五次取走剩下的a3,v5=a3⋅b5=25。
总价值∑vi=1+6+12+8+25=52 还是比较基础的一个区间DP
#include<bits/stdc++.h>
using namespace std;
const int N=;
int dp[N][N];
int a[N],b[N];
int main(){
int T,n;
for(scanf("%d",&T);T--;){
scanf("%d",&n);
for(int i=;i<=n;++i) scanf("%d",a+i);
for(int i=;i<=n;++i) scanf("%d",b+i);
for(int i=;i<=n;++i) for(int j=;j<=n;++j) dp[i][j]=;
for(int i=;i<=n;++i) for(int j=;j<=n-i+;++j) {
dp[j][j+i-]=max(dp[j+][j+i-]+b[n-i+]*a[j],b[n-i+]*a[j+i-]+dp[j][j+i-]);
}
printf("%d\n",dp[][n]);
}
}
题目描述
输入描述:
第一行一个数据组数T(T≤50)。
每组数据第一行n,给出结点总数(n≤100),下一行给出n个数字,表示每一个结点有几名栗酱的士兵,如果没有士兵,则代表该结点属于敌方。
之后给出一张n行n列的邻接矩阵,′Y′表示第i个结点和第j个结点存在道路将其连通。
输出描述:
对于每组数据每行给出一个数ans,表示为所求的答案,即所有与敌人结点直接相邻的己方结点的士兵数中的最小值最大是多少。
输入例子:
2
7
4 1 4 0 6 3 6
NNNNYNN
NNNNYNN
NNNNNNN
NNNNNNN
YYNNNNY
NNNNNNN
NNNNYNN
2
0 7
NY
YN
输出例子:
-1
7
-->
输入
2
7
4 1 4 0 6 3 6
NNNNYNN
NNNNYNN
NNNNNNN
NNNNNNN
YYNNNNY
NNNNNNN
NNNNYNN
2
0 7
NY
YN
输出
-1
7
其实就是二分后判定最小割就可以了,注意题目说要每个坑要保证有一个人。。。
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int INF=0x3f3f3f3f;
char mp[N][N];
int vis[N];
int dis[N],cnt[N],q[N],head[N],tot,S,T;
struct node{
int to,next,w;
}e[N*N*];
void add(int u,int v,int w){
e[tot].to=v;e[tot].next=head[u];e[tot].w=w;head[u]=tot++;
}
vector<int>amy,bs,ot;
bool bfs(){
memset(dis,-,sizeof(dis));
int r=,l=;
q[r++]=S;
dis[S]=;
while(l<r){
int u=q[l++];
for(int i=head[u];~i;i=e[i].next) {
int v=e[i].to;
if(dis[v]==-&&e[i].w>) {
q[r++]=v;
dis[v]=dis[u]+;
if(v==T) return true;
}
}
}
return false;
}
int dfs(int s,int low){
if(s==T||!low) return low;
int ans=low,a;
for(int i=head[s];~i;i=e[i].next) {
if(e[i].w>&&dis[e[i].to]==dis[s]+) {
if(a=dfs(e[i].to,min(ans,e[i].w))) {
ans-=a;
e[i].w-=a;
e[i^].w+=a;
if(!ans) return low;
}
}
}
if(low==ans) dis[s]=-;
return low-ans;
}
int main(){
int Ta,n;
for(scanf("%d",&Ta);Ta--;){
scanf("%d",&n);
memset(vis,,sizeof(vis));
tot=;
amy.clear(),bs.clear(),ot.clear();
memset(head,-,sizeof(head));
for(int i=;i<=n;++i) scanf("%d",cnt+i);
for(int i=;i<=n;++i) if(!cnt[i]) vis[i]=,amy.push_back(i);
for(int i=;i<=n;++i) scanf("%s",mp[i]+);
for(int i=;i<=n;++i) for(int j=i+;j<=n;++j) if(mp[i][j]=='Y') add(i,j,INF),add(j,i,INF);
if((int)(amy.size())==n||(int)(amy.size())==) {puts("-1");continue;}
for(int i=;i<(int)amy.size();++i) for(int j=head[amy[i]];~j;j=e[j].next) if(!vis[e[j].to]) vis[e[j].to]=,bs.push_back(e[j].to);
if(bs.size()==) {puts("-1");continue;}
for(int i=;i<=n;++i) if(!vis[i]) ot.push_back(i);
int l=,r=,ans,aas;
S=,T=n+;
while(l<=r) {
int mid=(l+r)>>;
tot=;
memset(head,-,sizeof(head));
for(int i=;i<=n;++i) for(int j=i+;j<=n;++j)
if(mp[i][j]=='Y'&&vis[i]!=&&vis[j]!=) add(i,j,INF),add(j,i,INF);
for(int i=;i<(int)ot.size();++i) add(S,ot[i],cnt[ot[i]]-),add(ot[i],S,);
for(int i=;i<(int)bs.size();++i) add(bs[i],T,mid),add(T,bs[i],);
for(int i=;i<(int)bs.size();++i) add(S,bs[i],cnt[bs[i]]),add(bs[i],S,);
int ans=;
while(bfs()) ans+=dfs(S,INF);
if(ans==(int)bs.size()*mid) l=mid+,aas=mid;
else r=mid-;
}
printf("%d\n",aas);
}
}
题目描述
满足(a'1+b1)%k = (a'2+b2)%k = …… = (a'm + bm)%k。
输入描述:
输出描述:
每一组数据输出一行,满足条件的连续子序列数量。
输入例子:
2
3 2 5
7 8 7
8 7
3 2 5
7 8 9
8 7
输出例子:
1
2
-->
输入
2
3 2 5
7 8 7
8 7
3 2 5
7 8 9
8 7
输出
1
2
备注:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+;
int chang[N],n,m,k,duan[N],nxt[N];
void get(){
int i=,j=-;
nxt[]=-;
while(i<m) {
if(j==-||duan[i]==duan[j]) {
if(duan[i+]==duan[j+]) nxt[++i]=nxt[++j];
else nxt[++i]=++j;
}
else j=nxt[j];
}
}
int KMP(){
get();
int i=,j=;
int sum=;
while(i<n) {
if(chang[i]==duan[j]) ++j,++i;
else {
j=nxt[j];
if(j==-) ++i,j=;
}
if(j==m) ++sum;
}
return sum;
}
int main(){
int T;
for(scanf("%d",&T);T--;){
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<n;++i) scanf("%d",chang+i),chang[i]%=k;
for(int i=;i<m;++i) scanf("%d",duan+i),duan[i]%=k;
for(int i=;i<n-;++i) chang[i]=(chang[i+]-chang[i]+k)%k;
for(int i=;i<m-;++i) duan[i]=(duan[i+]-duan[i]+k)%k;
for(int i=;i<m-;++i) duan[i]=(k-duan[i])%k;
--m;--n;
duan[m]=-;
printf("%d\n",KMP());
}
}
题目描述
栗酱这次遇到了一个大麻烦,她手里只有一张大钞,面值为A元,但是现在临时需要花费B块钱了。
她的花费非常紧急,所以她来到一个小卖部来兑,可是小卖部的老板态度极差,拒绝了栗酱的直接兑换请求。
栗酱没有办法,周边也没有别的店,栗酱只好在店里强行花费一些钱来获取这个零散的B块钱了。
输入描述:
多组数据,数据第一行T表示数据组数。
每组数据一行,A,B分别代表栗酱当前的大钞和需要的零钱。
输出描述:
每组数据一行,输出最少花费。
输入例子:
2
0.05 0.01
0.10 0.05
输出例子:
0.02
0.01
-->
输入
2
0.05 0.01
0.10 0.05
输出
0.02
0.01
说明
第一个样例:
如果付0.01块,老板会找你两个0.02。
花0.02老板就没办法了,只能找你一个0.02,一个0.01,或三个0.01
备注:
T≤100,
a>b,
a,b∈{0.01,0.02,0.05,0.10,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00} http://blog.csdn.net/irish_moonshine/article/details/78881607 暂时分析不清
浙工大新生赛莫队处理+区间DP+KMP+分析题的更多相关文章
- 2017年浙工大迎新赛热身赛 L cayun日常之赏月【易错特判】
题目描述(https://www.nowcoder.com/acm/contest/51#question) 在cayun星球月亮大小都有一个规律,月亮为每30天一个周期,在这30天的周期里,月亮的大 ...
- CF 617E【莫队求区间异或和】
E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input s ...
- HDU5381【莫队算法+区间GCD特性】
前言: 主要最近在刷莫队的题,这题GCD的特性让我对莫队的使用也有了新的想法.给福利:神犇的一套莫队算法题 先撇开题目,光说裸的一个莫队算法,主要的复杂度就是n*sqrt(n)对吧,这里我忽略了一个左 ...
- 2016 年沈阳网络赛---QSC and Master(区间DP)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5900 Problem Description Every school has some legend ...
- 区间dp(入门题)
区间dp:顾名思义就是在区间上进行动态规划,通过合并小区间求解一段区间上的最优解. 常见模板: for(int len=1;len<n;len++){//区间长度 for(int be=1;be ...
- CF 149D Coloring Brackets(区间DP,好题,给配对的括号上色,求上色方案数,限制条件多,dp四维)
1.http://codeforces.com/problemset/problem/149/D 2.题目大意 给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色, ...
- 2017年浙工大迎新赛热身赛 J Forever97与寄信 【数论/素数/Codeforces Round #382 (Div. 2) D. Taxes】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 131072K,其他语言262144K64bit IO Format: %lld 题目描述 Forever97与未央是一对笔友,他们经常互 ...
- 2017年浙工大迎新赛热身赛 A 毕业设计选题 【结构体排序】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 65536K,其他语言131072K64bit IO Format: %lld 题目描述 又到了一年一度,大四老学长们毕业设计选题的时候, ...
- 一道区间DP的水题 -- luogu P2858 [USACO06FEB]奶牛零食Treats for the Cows
https://www.luogu.org/problemnew/show/P2858 方程很好想,关键我多枚举了一次(不过也没多大关系) #include <bits/stdc++.h> ...
随机推荐
- SpringBoot @ConfigurationProperties详解
文章目录 简介 添加依赖关系 一个简单的例子 属性嵌套 @ConfigurationProperties和@Bean 属性验证 属性转换 自定义Converter SpringBoot @Config ...
- HDU 5954 Do Not Pour Out
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #defi ...
- 【集群实战】Rsync试题-异机数据备份解决方案
企业案例:Rsync上机实战考试题: 某公司有一台Web服务器,里面的数据很重要,但是如果硬盘坏了,数据就会丢失,现在领导要求你把数据在其它机器上做一个周期性定时备份. 要求如下: 每天晚上00点整在 ...
- qemu-img 整理
qemu-img命令语法: qemu-img command [command options] check命令: check [-f fmt < qcow2 | qed | vdi >] ...
- 初见Ajax——javascript访问DOM的三种访问方式
最近好啰嗦 最近在一间小公司实习,写一些小东西.小公司嘛,人们都说在小公司要什么都写的.果真是. 前端,后台,无论是HTML,CSS,JavaScript还是XML,Java,都要自己全包了.还好前台 ...
- Java——类的访问修饰符
1.java中外部类的访问修饰符有如下四种: public,默认,abstract,final // public,默认,abstract,final. public class Test1 {} c ...
- springboot配置静态资源访问路径
其实在springboot中静态资源的映射文件是在resources目录下的static文件夹,springboot推荐我们将静态资源放在static文件夹下,因为默认配置就是classpath:/s ...
- Spring官网阅读(八)容器的扩展点(三)(BeanPostProcessor)
在前面两篇关于容器扩展点的文章中,我们已经完成了对BeanFactoryPostProcessor很FactoryBean的学习,对于BeanFactoryPostProcessor而言,它能让我们对 ...
- Coursera课程笔记----计算导论与C语言基础----Week 10
C程序中的数组(Week 10) 一维数组 数组的定义 类型 数组名[常量表达式] int sheep[10] 定义数组时,[]内必须为常量表达式 可以用const int 可以在main函数前,#d ...
- redis crackit入侵事件总结
今天发现服务器有异常进程/opt/yam/yam,上网搜了搜,是由于redis未授权引起的入侵,查了些资料,这里做下总结. 1. 现象 有以下其一现象就要注意是否被入侵 crontab -l 可以看到 ...