【2013杭州区域赛】部分题解 hdu4770—4780
1008:
题意:
有20W个数,每个数都在20W以内,现在有20W个询问,每次询问L,R区间内不会打架的数有多少个
定义两个数不互质 就会打架
解法:
脑洞很大的一道题,先要进行预处理,对每一个数预处理出 最大的,没有跟他不互质数(即这个数不会打架)的区间
显然可以通过找到这个数左边和右边的第一个跟他互质的数来求得此区间,那么这个怎么求呢,发现可以通过枚举当前数的质因数找到
我们先处理,每一个数左边的最后一次出现的坐标,这样每扫到一个数,都只需要对这个数及其质因数进行更新
找到了每个数的上述区间后,我们发现设某个数的上述区间为 [L,R],这个数自己的位置为pos,现在对于一个询问[a,b]
这个数是询问中的一个答案的条件就是 L<=a,b<=R 且 a<=pos<=b。现在可以离线进行更新和查询
我们可以在L 处将区间[pos,R]位置的值+1,并在pos处对该区间的值 -1,那么对于某个查询[a,b] 只需要在扫到a的时候,单点查询b的值即可
代码:
#include <bits/stdc++.h>
using namespace std;
int a[];
int l[];
int r[];
int pre[];
vector<int>d[];
bool np[];
void setprime(int maxn)
{
memset(np,,sizeof(np));
for(int i=; i<=maxn; i++)
{
if(np[i]==)
d[i].push_back(i);
for(int j=i+i; j<=maxn; j+=i)
{
np[j]=;
if(np[i]==)
d[j].push_back(i);
}
}
}
int n,m;
struct node
{
int type; //-1:+1 -2:-1,else ²éѯ;
int pos;
int num;
bool operator <(const node a)const
{
if(pos!=a.pos)
return pos<a.pos;
else
{
return type<a.type;
}
}
};
int ans[];
vector<node>q;
int t[];
int lowbit(int x)
{
return x&(-x);
} int getSum(int x)
{
int sum = ;
while(x)
{
sum += t[x];
x -= lowbit(x);
}
return sum;
} void add(int x , int val)
{
while(x <=)
{
t[x] += val;
x += lowbit(x);
}
}
void init()
{
memset(t,,sizeof(t));
q.clear();
memset(l,,sizeof(l));
for(int i=; i<=n; i++)
{
r[i]=n+;
}
}
int main()
{
//freopen("in.txt","r",stdin);
setprime();
while(scanf("%d%d",&n,&m),n+m)
{
init();
for(int i=; i<=n; i++)
{
scanf("%d",a+i);
}
memset(pre,,sizeof(pre));
for(int i=; i<=n; i++)
{
for(int j=; j<(int)d[a[i]].size(); j++)
{
int now=d[a[i]][j];
l[i]=max(pre[now],l[i]);
pre[now]=i;
}
l[i]++;
}
memset(pre,0x3f,sizeof(pre));
for(int i=n; i>; i--)
{
for(int j=; j<(int)d[a[i]].size(); j++)
{
int now=d[a[i]][j];
r[i]=min(pre[now],r[i]);
pre[now]=i;
}
r[i]--;
q.push_back(node {-,l[i],i});
q.push_back(node {m,i,i});
}
for(int i=; i<m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
q.push_back(node {i,u,v});
}
//printf("%d\n",q.size());
sort(q.begin(),q.end());
for(int i=; i<(int)q.size(); i++)
{
node now=q[i];
if(now.type==-)
{
add(now.num,);
add(r[now.num]+,-);
}
if(now.type==m)
{
add(now.num,-);
add(r[now.num]+,);
}
if(now.type>=&&now.type<m)
{
ans[now.type]=getSum(now.num);
}
}
for(int i=; i<m; i++)
{
printf("%d\n",ans[i]);
}
}
return ;
}
1009:
题意:
有g种不同颜色的小球,b个袋子,每个袋子里面有若干个每种小球
两人轮流取袋子,当袋子里面的同色小球有s个时,会合并成一个魔法球,并被此次取袋子的人获得
成功获得魔法球的人可以再次取
求二者都进行最优策略之后两人所得魔法球个数差
解法:
数据不大,考虑搜索,发现不行,于是可以记忆化搜索,转移不难想到
代码:
#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define MAXN 10000
typedef struct Node
{
int a,b;
}node;
node dp[];
bool vi[];
int num[][];
int p[];
int g,b,s,k,m,x;
void dfs(int state,int turn)
{
if(state==(<<b)-)
{
dp[state].a=;
dp[state].b=;
return ;
}
if(vi[state])
{
return ;
}
int ok;
node t;
node ans;
ans.a=-;
ans.b=;
int pp[];
memcpy(pp,p,sizeof(pp));
for(int i=;i<b;i++)
{
t.a=;
t.b=;
ok=;
if(state&(<<i))
continue;
int st=state|(<<i); //状态
for(int j=;j<g;j++)
{
p[j]+=num[i][j];
ok+=p[j]/s;
p[j]%=s;
}
int tur=ok?turn:!turn;//是否交换选手
dfs(st,tur);
memcpy(p,pp,sizeof(pp));
t.a+=ok;
if(tur==turn) //子状态的先手所要转移到的状态相同
{
t.a+=dp[st].a;
t.b+=dp[st].b;
}
else //选手交换了
{
t.b+=dp[st].a;
t.a+=dp[st].b;
}
if(t.a-t.b>ans.a-ans.b)
{
ans=t;
}
}
vi[state]=;
dp[state]=ans;
return ;
}
int main()
{
while(scanf("%d%d%d",&g,&b,&s),g+b+s)
{
memset(num,,sizeof(num));
for(int i=;i<b;i++)
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&x);
num[i][x-]++;
}
}
memset(p,,sizeof(p));
memset(vi,,sizeof(vi));
dfs(,);
printf("%d\n",dp[].a-dp[].b);
}
return ;
}
【2013杭州区域赛】部分题解 hdu4770—4780的更多相关文章
- HDU 4745 Two Rabbits (2013杭州网络赛1008,最长回文子串)
Two Rabbits Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...
- HDU 4747 Mex (2013杭州网络赛1010题,线段树)
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 4741 Save Labman No.004 (2013杭州网络赛1004题,求三维空间异面直线的距离及最近点)
Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 4739 Zhuge Liang's Mines (2013杭州网络赛1002题)
Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【2013南京区域赛】部分题解 hdu4802—4812
上周末打了一场训练赛,题目是13年南京区域赛的 这场题目有好几个本来应该是我擅长的,但是可能是太久没做比赛了各种小错误代码写的也丑各种warusn trush搞得人很不爽 全场题之一的1002也没有想 ...
- 2013杭州现场赛B题-Rabbit Kingdom
杭州现场赛的题.BFS+DFS #include <iostream> #include<cstdio> #include<cstring> #define inf ...
- 【2013长沙区域赛】部分题解 hdu4791—4801
1001: 签到题,二分一下即可 代码: #include <set> #include <map> #include <cmath> #include <c ...
- 2013 ACM区域赛长沙 C Collision HDU 4793
题意:在平面上0,0点,有一个半径为R的圆形区域,并且在0,0点固定着一个半径为RM(<R)的圆形障碍物,现在圆形区域外x,y,有一个半径 为r的,并且速度为vx,vy的硬币,如果硬币碰到了障碍 ...
随机推荐
- C++之智能指针
导读 一直对智能指针有一种神秘的赶脚,虽然平时没怎么用上智能指针,也就看过STL中的其中一种智能指针auto_ptr,但是一直好奇智能指针的设计因此,今天看了一下<C++ Primer Plus ...
- checkbox 全选/取消
<html><script language=javascript>function selectAll(){var a = document.getElementsByTag ...
- Java POI 两种导出方式
这里面包含了模板导出方法和自定义模板进行导出 package jp.co.syspro.poo.action.hibikoyou; import java.io.ByteArrayOutputStre ...
- System.Management命名空间
提供对大量管理信息和管理事件集合的访问,这些信息和事件是与根据 Windows 管理规范 (WMI) 结构对系统.设备和应用程序设置检测点有关的.应用程序和服务可以使用从 ManagementObje ...
- OC - 20.多图下载
效果图 常见问题及解决方法 图片重复下载 将内存保存在内存或沙盒中. 若下载的图片量较大,则会出现UI界面不流畅的现象 在子线程中执行下载操作,然后回到主线程成中进行UI界面的刷新. 由于cell的循 ...
- Linux 寻找安装路径
1.whereis 语法: # whereis [-bmsu] 文件或者目录名称 参数说 明: -b : 只找二进制文件 -m: 只找在说明文件manual路径下的文件 -s : 只找sou ...
- java 懒汉式--初步解决安全问题
2016-07-28 00:10:14 懒汉式: class text { public String k; private static text t=null;//右边代码结构比上边饿 ...
- 可以让PHP编程事半功倍的类库
在用php开发网站的时候,使用面向对象的方法确实可以提高代码复用率,减少代码冗余.而对初学者更友好的是,PHP开发网站所需要的大部分类库,网上都有十分优秀的类库存在了.作为一个程序猿当然不能重复制造轮 ...
- js学习笔记之:时间(三)
今天来学习一个简单的时间应用:时间的倒影,如图所示: 主要知识点: 1 获取系统的时间值:2 建立一个div的倒影 div的倒影主要利用css来控制,函数值为:filter:flipv() 步骤 ...
- 字符串截取slice() substring() substr()的区别?
获取子字符串 slice() substr() substring() 不会修改字符串本身,他们只是返回一个基本类型的字符串值 var str='abcdefghijklmn'; ...