Bestcoder Round 47 && 48
1.Senior's Array(hdu 5280)
题目大意:给出大小为N的数组和P,求将数组中的某个元素替换为P后的最大连续子段和。N<=1000
题解:
1.送分题,比赛的时候只想到枚举替换的元素然后贪心找最大连续子段和.时间复杂度O(N2)
2.实际上有更好的做法。类似线段树的合并,枚举替换元素的时候 可以把左右两边的答案合并.F[i]表示以i结尾,G[i]表示以i开头的最优解.合并的时候只要考虑把中间的P用起来,即
A[x]+max(0,F[x-1])+max(0,G[x+1]) . 时间复杂度O(N).
2.Senior's Gun(hdu 5281)
题目大意:给出两个大小分别为N,M的数组A,B,将这两个数组的元素配对起来,配对的得分为A[i]-B[j](只有A[i]>B[j]才可以把A[i],B[j]配对).要求得分和最大。
题解:
1.比赛的时候想到贪心地把A中大的和B中小的配对。 但是不会证明,感觉不大靠谱。然后就只A了T1 滚粗了。
2.官方题解很简洁:二分出最大可能的配对数,然后枚举配对数,取最大的答案。 这么简洁的题解像我这么弱的可能会一下反应不过来,所以来解释一下: 假设有2N个数能两两配对,那么配对的得分总和是一定的,即A的总和减去B的总和。 所以枚举了所有的配对数,也就枚举了所有的配对情况。 再提一下二分的时候怎么判断可行性:从小到大排序,然后小的和小的对,大的和大的对。 如果这样不行,那么一定不存在可行方案。 脑残的我又想来证明一下了(果然我不适合OI...OIer不是只要记住结论就好了么。。):假设存在某种方案不是这样配对的,如果A,B数组已经从小到大排序,如果A[i]和B[j]配对就在他们之间连一条线。那么至少有两条线是交叉的.显然把交叉的线 弄成不交叉 即交换配对对象 也是满足条件的。 那么重复这样的操作 最终得到我们一开始的配对方式。
3.看了下别人的代码,发现1中的方法也是可行的。如果n<m 把B中最小的n个拿出来就好。 如果n>m把A中最大的m个拿出来就好。 所以只考虑n=m的情况。
考虑A中的两个元素P,Q,P<=Q. B中的两个元素S,T,S<=T.
如果Q<S,那么不能匹配任意一个.
如果P>=T,那么可以随便怎么匹配,得分为P+Q-S-T。 可以认为是PT,QS匹配。
除去上面的两种情况,也就是Q>=S,P<T的时候。这时候一定是QS匹配最优。我们可以从赚差值的角度理解。假设如果A[i]-A[j]<0也可以匹配,但实际得分却是0,这样我们就赚了
这个负的值。所以要想尽可能多赚这个负的值,要让A中小的P和B中大的T匹配。
。。憋出个证明蛋疼死了。而且感觉还是不大完美。 其实还是感觉官方题解好理解,但大多数人貌似都是3中的方法。
3.Senior's String(hdu 5282)
题目大意:给出2个字符串AB,求它们的LCS,假设长度是len,再求A中长度为len的子序列中有多少个是B的子序列。(一开始以为是LCS的个数,仔细想想其实不是。。)
题解:
先搞出求LCS时的dp数组。然后再做一次动态规划。F[i][j]表示A[1..i]的长度为dp[i][j]的子序列中有多少个是B[1...j]的子序列。
1.考虑不选A[i],那么必须有dp[i-1][j]==dp[i][j]. F[i][j]+=F[i-1][j].
2.考虑选 A[i],设p是满足p<=j && B[p]=A[i]的最大的p. 那么必须有dp[i-1][p-1]+1=dp[i][j] . F[i][j]+=F[i-1][p-1].
感觉这个dp略吊啊。
4.Senior's Fish(hdu 5283)
题目大意:
给出坐标系上的一个矩形,和一些点(编号1-N),要求支持以下操作:
1.把编号属于区间[L,R]的点横坐标+x(x>0).
2.把编号属于区间[L,R]的点纵坐标+x(x>0).
3.查询在矩形中点的个数。
题解:
1.这题要充分利用点的坐标是单调增的这个性质。 也就是说 一个点出了矩形 就不可能再进来了。 然后可以把询问拆成4个,有多少个点在某个点左下方的询问。
2.对xy坐标分别建4棵线段树,然后如果某个坐标超过了上界,就把它从线段树里删去。 这里有个技巧,就是可能一次操作之后有多个点超过了上界,但是这些点又不是连续的,我们可以一个一个删,因为每个点只会被删去一次,复杂度有保证. 只要每次找坐标值最大的点,如果越界了就删去,并把他的值改为负无穷。 具体实现起来好像有点麻烦,要好多线段树...我就没有写..懒。
5.wyh and pupil(hdu 5285)
题目大意:给出无向图的一些边,要求把点分为2个非空集合,集合内不能有边,且第一个集合点最多。
题解:
1.首先判断一下是不是二分图,如果不是无解。
2.可以发现连通块之间是独立的,只要每个连通块里选尽量多的点放到第一个集合就好。所以对每个连通块二分图染色,选择点多的那种颜色。
3.另外考虑特殊情况,只有一个点和没有边的情况。 比赛的时候没考虑 FST了。
6.wyh and sequence(hdu 5286)
题目大意:Q次询问区间[Li,Ri]中,把所有数去重之后,设第i个数pi出现了ki次, 求sigma(pi^ki).
题解:
1.这题写了4K左右的代码...BC难得有代码量这么大的题。感觉我就算会做也不可能在1个小时之内写出来A掉。跪nodgd分块大神!!
2.太难表述。。直接copy官方题解:
3.另外这题卡常数。。极限数据我的程序过不了,但是OJ上还是AC了。由于要离散化,我一开始写的时候每次都从map里取出那个元素...结果复杂度多了个log,死都查不出来。。
贴个代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std; typedef long long ll;
typedef pair<int,int> pii;
const int N=,Mod=1e9+; int n,Q,unit,tot;
int A[N],v[N],cnt[N],cur[N],ans[][],rk[N];
int S[N][],L[N],R[N],id[N],lb[],rb[];
vector<int> g[N];
map<int,int> mp; inline int Add(int x,int y){return (x+y)%Mod;}
inline int Mul(int x,int y){return 1ll*x*y%Mod;} void Init()
{
mp.erase(mp.begin(),mp.end()); tot=;
for (int i=;i<=n;i++)
{
if (!mp.count(A[i]))
{
mp[A[i]]=;
v[++tot]=A[i];
}
}
sort(v+,v+tot+);
for (int i=;i<=tot;i++) mp[v[i]]=i;
for (int i=;i<=n;i++) rk[i]=mp[A[i]]; for (int i=;i<=tot;i++) g[i].clear(),g[i].push_back(),cur[i]=;
for (int i=;i<=n;i++)
{
cur[rk[i]]=Mul(cur[rk[i]],A[i]);
g[rk[i]].push_back(cur[rk[i]]);
} unit=sqrt(n)+;
L[]=,id[]=;
for (int i=;i<=n;i++)
{
id[i]=(i-)/unit+;
L[i]=(id[i]==id[i-])? L[i-]:i;
}
R[n]=n;
for (int i=n-;i>=;i--) R[i]=(id[i]==id[i+])? R[i+]:i; for (int i=;i<=id[n];i++) lb[i]=(i-)*unit+,rb[i]=min(i*unit,n); for (int i=;i<=tot;i++) cnt[i]=;
for (int i=;i<=n;i++)
{
cnt[rk[i]]++;
if (i%unit== || i==n)
{
for (int j=;j<=tot;j++)
S[j][id[i]]=cnt[j];
}
} for (int i=;i<=id[n];i++)
{
for (int j=;j<=tot;j++) cnt[j]=;
for (int j=i;j<=id[n];j++)
{
ans[i][j]=(i==j)? :ans[i][j-];
for (int k=lb[j];k<=rb[j];k++)
{
int x=rk[k]; cnt[x]++;
ans[i][j]=Add(ans[i][j],-g[x][cnt[x]-]);
ans[i][j]=Add(ans[i][j],g[x][cnt[x]]);
ans[i][j]=Add(ans[i][j],Mod);
}
}
}
memset(cnt,,sizeof(cnt));
} int Query(int l,int r)
{
int Ans=;
if (id[r]-id[l]<=)
{
for (int i=l;i<=r;i++)
{
int x=rk[i];
Ans=Add(Ans,-g[x][cnt[x]]);
Ans=Add(Ans,g[x][++cnt[x]]);
Ans=Add(Ans,Mod);
}
for (int i=l;i<=r;i++) cnt[rk[i]]=;
}
else
{
Ans=ans[id[l]+][id[r]-];
for (int i=l;i<=R[l];i++)
{
int x=rk[i];
Ans=Add(Ans,-g[x][cnt[x]+S[x][id[r]-]-S[x][id[l]]]);
Ans=Add(Ans,g[x][++cnt[x]+S[x][id[r]-]-S[x][id[l]]]);
Ans=Add(Ans,Mod);
}
for (int i=L[r];i<=r;i++)
{
int x=rk[i];
Ans=Add(Ans,-g[x][cnt[x]+S[x][id[r]-]-S[x][id[l]]]);
Ans=Add(Ans,g[x][++cnt[x]+S[x][id[r]-]-S[x][id[l]]]);
Ans=Add(Ans,Mod); }
for (int i=l;i<=R[l];i++) cnt[rk[i]]=;
for (int i=L[r];i<=r;i++) cnt[rk[i]]=;
}
return Ans;
} void Read(int &x)
{
x=; char ch=getchar();
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='') x=x*+ch-'',ch=getchar();
} int main()
{
int T,lastans,x,y,l,r;scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&Q);
for (int i=;i<=n;i++) Read(A[i]);
Init(); lastans=;
for (int i=;i<=Q;i++)
{
Read(x),Read(y);
x^=lastans,x%=n,x++;
y^=lastans,y%=n,y++;
l=min(x,y),r=max(x,y);
lastans=Query(l,r);
printf("%d\n",lastans);
}
} return ;
}
Bestcoder Round 47 && 48的更多相关文章
- BestCoder Round #47
1001 Senior's Array 题目链接:1001 题意:给你一个长度为n的序列,你必须修改序列中的某个数为P,求修改后的最大连续子序列和. 思路:数据量比较小,可以直接暴力做, 枚举序列的每 ...
- BestCoder Round #47 1003
solution : 就按题解敲了一遍,好久没写这种dp ; ; LL f[MAX][MAX]; ]; scanf( scanf(,b+); ...
- HDU 5281 BestCoder Round #47 1002:Senior's Gun
Senior's Gun Accepts: 235 Submissions: 977 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- HDU 5280 BestCoder Round #47 1001:Senior's Array
Senior's Array Accepts: 199 Submissions: 944 Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- 二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil
题目传送门 /* 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 每一次二分图匹配时,将点多的集合加大最后第一个集合去 注意:n <= 1,no,两 ...
- BestCoder Round #14
Harry And Physical Teacher Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- DP BestCoder Round #50 (div.2) 1003 The mook jong
题目传送门 /* DP:这题赤裸裸的dp,dp[i][1/0]表示第i块板放木桩和不放木桩的方案数.状态转移方程: dp[i][1] = dp[i-3][1] + dp[i-3][0] + 1; dp ...
- BestCoder Round #89 02单调队列优化dp
1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01 HDU 5944 水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...
- BestCoder Round #90 //div all 大混战 一题滚粗 阶梯博弈,树状数组,高斯消元
BestCoder Round #90 本次至少暴露出三个知识点爆炸.... A. zz题 按题意copy Init函数 然后统计就ok B. 博弈 题 不懂 推了半天的SG..... 结果这 ...
随机推荐
- tableLayoutPanel的使用
https://msdn.microsoft.com/en-us/library/ms171687(v=vs.110).aspx Controls in a TableLayoutPanel cont ...
- Solr atomic update JSON方式
http://yonik.com/solr/atomic-updates/ Solr supports several modifiers that atomically update values ...
- 28.zookeeper单机(Standalones模式)和集群搭建笔记
zookeeper单机(Standalones模式)和集群搭建: 前奏: (1).zookeeper也可以在windows下使用,和linux一样可以单机也可以集群,具体就是解压zookeeper-3 ...
- React 快速入门小记
大约半个月前,我一直在思考一个问题,Angular.React 和 Vue,究竟该学什么? 听取了几位前辈的意见,也综合考虑了各方面的原因,最终选择了 React,希望我"没有选错" ...
- Hook机制里登场的角色
稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 ...
- H5手机端关注的问题
手机端页面写css时应该注意的问题: 设备的屏幕尺寸 设备的分辨率 用户的操作习惯以及点击区域的大小 移动端浏览器的特性 鉴于分辨率等情况而引出的图片尺寸.布局方式等诸多细节问题 ...
- js this理解
原文链接:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html this是js语言的几个关键字,代表 ...
- iOS 页面间几种传值方式(属性,代理,block,单例,通知)
第二个视图控制器如何获取第一个视图控制器的部分信息 例如 :第二个界面中的lable显示第一个界面textField中的文本 这就需要用到属性传值.block传值 那么第一个视图控制器如何获的第二个视 ...
- T-SQL、JET SQL、PL-SQL
数据库分为网状.层状.关系.对象四种类型,目前的数据库一般都是属于关系数据库(包括MYSQL和SQL SERVER),网状.层状基本上已成历史,对象类型尚未普及. SQL 语言是有 ANSI 标准的. ...
- 判断iframe是否加载完成的完美方法
var iframe = document.createElement("iframe"); iframe.src = "http://www.jb51.net" ...