10.9 顾z校内互坑题
T1 (help)
题意简述
给定一个长度为\(n\)的序列。然后给出多组询问.
询问\([l,r]\)区间内不等于该段区间\(gcd\)的数的个数。
分析
看到区间问题,优先考虑线段树 or 树状数组
貌似可以树状数组做.但维护起来会比较麻烦.
下面讲解线段树做法
线段树做法.
首先,线段树要维护区间\(gcd\)
这里使用\(tr[o]\)代表当前区间的区间\(gcd\).
如何记录答案?
很显然,我们直接记录\([l,r]\)区间内不等于该段区间\(gcd\)的数的个数会比较麻烦.
因此,考虑记录等于该段区间\(gcd\)的数的个数.(在线段树上维护.
我们使用数组\(sum[o]\)代表当前区间中等于区间\(gcd\)的数的个数.
而每次询问的区间长度又已知,所以我们每一次询问的结果就是
\]
PS:\(gd\)函数是用来求解区间\(gcd\)的
如何更新/传递\(sum\)数组呢?
首先,我们会把叶子节点的\(sum\)标记为\(1\)(只会有一个数啊 qwq.
然后当向上传递的时候,我们的区间\(gcd\)会变化.
这里写一下区间\(gcd\)的上传操作
\]
发现区间\(gcd\)是会变化的,因此我们的\(sum\)数组也要随之变化.
我们需要判断的是\(tr[o]\)的值是\(tr[ls]\)还是\(tr[rs]\)。
一.\(tr[o]\)来自\(tr[ls]\)
此时我们的\(sum[o]\)可以接受\(sum[ls]\)的贡献,
二.\(tr[o]\)来自\(tr[rs]\)
此时我们的\(sum[o]\)可以接受\(sum[rs]\)的贡献.
三. \(tr[o]\)同时来自\(tr[ls]\)和\(tr[rs]\)
此时便可以同时获得贡献.
因此,\(sum\)数组的转移就可以写成这样.
\]
此时,知道了\(sum\)数组,我们的问题就得以解决.
代码
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#define N 5000008
#define ls o<<1
#define rs o<<1|1
#define R register
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int tr[N],sum[N],n,m;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
inline void up(int o)
{
tr[o]=gcd(tr[ls],tr[rs]);
sum[o]=(tr[o]==tr[ls] ? sum[ls]:0)+(tr[o]==tr[rs] ? sum[rs]:0);
}
void build(int o,int l,int r)
{
if(l==r)
{
in(tr[o]);
sum[o]=1;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(o);
return;
}
int gd(int o,int l,int r,int x,int y)
{
if(x<=l and y>=r)return tr[o];
int mid=(l+r)>>1;
if(y<=mid) return gd(ls,l,mid,x,y);
if(x>mid) return gd(rs,mid+1,r,x,y);
return gcd(gd(ls,l,mid,x,y),gd(rs,mid+1,r,x,y));
}
int query(int o,int l,int r,int x,int y,int k)
{
if(x<=l and y>=r) return tr[o]== k ?sum[o]:0;
int mid=(l+r)>>1,res=0;
if(y<=mid) return query(ls,l,mid,x,y,k);
if(x>mid) return query(rs,mid+1,r,x,y,k);
return query(ls,l,mid,x,y,k)+query(rs,mid+1,r,x,y,k);
}
int main()
{
//freopen("help.in","r",stdin);
//freopen("help.out","w",stdout);
in(n);
build(1,1,n);
in(m);
for(R int l,r;m;m--)
{
in(l),in(r);
printf("%d\n",r-l+1-query(1,1,n,l,r,gd(1,1,n,l,r)));
}
fclose(stdin);
fclose(stdout);
return 0;
}
T2(escape)
题意简述
给定\(n\)个数,这\(n\)个数均在\(1-n\)的范围内,其中有一个数出现了两次,其余数均出现了一次.让你求出这个出现两次的数.
数据范围
\(2\leq n \leq10^7\)
时空限制
\(2000ms/16MB\)
吐槽
如果数组给的足够大,相信大家都能切掉这种傻逼题.
但是如果不能开数组呢?
其实空间想给1MB来着,结果标程跑不动 QAQ
这时候就需要用到我们的\(Math\)方法
分析
首先,从题目中大家应该都能得到一个信息.
这\(n\)个\(1-n\)的数中,如果一个数出现了两次,且其他数都只出现了一次,那么必定有一个数没出现过.
接下来进入数学推导时间.~w~
数学推导
我们设这个出现两次的数为\(x\),没有出现的数为\(y\),
首先很明显的一个关系:
\]
此方程左侧部分可求,如何求解右侧部分?
明显,一个方程解两个未知数不显示.
我们需要再找另一个关系.
考虑到\(\sum\),我们为何不考虑\(\prod\)呢?
手推一下可以发现一个新的关系(其实应该用不到手推) qwq
\]
然后解方程.
\]
再把式子小小的变形一下.
令\(\sum_{i=1}^{n}a_i-\sum_{i=1}^{n}i=d\)
令\(\frac{\prod_{i=1}^{n}a_i}{\prod_{i-1}^{n}i}=p\)
\]
推知
\]
建议手推,中间过程不继续放出.
最终推知
\]
因此
\]
题目得解.
由于\(\prod\)操作会超级大.
因此,此题为模意义下的解方程.
代码
PS:代码中的变量与推导部分的变量不符
#include<cstdio>
#include<cctype>
#define mod 19260817
#define R register
using namespace std;
inline long long ksm(long long x,long long y)
{
long long res=1;
for(;y;y>>=1,x=x*x%mod)
if(y&1)res=res*x%mod;
return res;
}
long long n,k,suma,sum,paia=1,pai=1;
long long c,d;
int main()
{
//freopen("escape.in","r",stdin);
//freopen("escape.out","w",stdout);
scanf("%lld",&n);
for(R int i=1;i<=n;i++)
{
R long long x;
scanf("%lld",&x);
(suma+=x)%=mod;
(sum+=i)%=mod;
(pai*=i)%=mod;
(paia*=x)%=mod;
}
c=suma-sum;
d=paia*ksm(pai,mod-2)%mod;
long long x=(c*ksm(d-1,mod-2)+c);
printf("%lld",(x%mod+mod)%mod);
fclose(stdin);
fclose(stdout);
return 0;
}
T3(cure)
原题为\(「JOI 2017 Final」\)焚风现象
题解你们如果看得懂日文就去看看 -->https://www.ioi-jp.org/joi/2016/2017-ho/2017-ho-t1-review.pdf
分析
首先,这是一个差分模板题,不过应该不是很容易看出来.
涉及到了区间修改与单点查询.(我相信有人会写数据结构的.
但是这里的单点查询就是一个固定的点\(n\)。
首先考虑为什么可以差分去做?
题目中的描述就暗示着我们进行差分啊.
首先我们发现了题目中的这一句话
风的温度随海拔升降而变化。
而,每个地点的海拔已知,所以我们可以在输入的时候求出每个位置的海拔差.
做法
根据海拔差,我们又可以求出每个位置的温度.由于\(n\)位置不会变,且一直为最后一个位置.
所以我们可以累加\(ans\).(因为最后一个位置\(n\)永远不会变。
而且考虑到某一段区间的海拔变化,相对位置不会变,我们只需要考虑从起始位置\(l\)的温度变化,后面到达\(r\)的温度就随之变化.
这里需要注意的位置就是当\(r==n\)的时候,是不需要变化\(r+1\)位置的海拔与温度的.
即我们的\(ans\)是不需要改变的.而改变的话,需要考虑相对高度的变化.我相信大家能懂的 qwq.
代码
#include<cstdio>
#include<cstring>
#include<cctype>
#define N 200005
#define R register
using namespace std;
long long n,q,s,t;
long long A[N],last,ans;
inline void in(long long &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
inline long long get(long long x)
{
return x > 0 ? -(x*s) : -(x*t) ;
}
int main()
{
//freopen("cure.in","r",stdin);
//freopen("cure.out","w",stdout);
in(n),in(q),in(s),in(t);
in(last);
for(R int i=1;i<=n;i++)
{
R long long x;
in(x);
A[i]=x-last;
last=x;
ans+=get(A[i]);
}
for(R long long x,y,z;q;q--)
{
in(x),in(y),in(z);
ans-=get(A[x]);
A[x]+=z;
ans+=get(A[x]);
if(y!=n) ans-=get(A[y+1]),A[y+1]-=z,ans+=get(A[y+1]);
printf("%lld\n",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}
还有标程很神奇
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
ll s1,s2;
ll dif[300001];
ll get(ll t)
{
if(t>0)return -s1*t;
else return -s2*t;
}
int main()
{
int num,query;
scanf("%d%d%lld%lld",&num,&query,&s1,&s2);
vector<int>v;
for(int i=0;i<=num;i++)
{
int z;
scanf("%d",&z);
v.push_back(z);
}
ll ans=0;
for(int i=0;i<num;i++)
{
dif[i]=v[i+1]-v[i];
ans+=get(dif[i]);
}
for(int i=0;i<query;i++)
{
int za,zb,zc;
scanf("%d%d%d",&za,&zb,&zc);
ans-=get(dif[za-1]);
dif[za-1]+=zc;
ans+=get(dif[za-1]);
if(zb!=num)
{
ans-=get(dif[zb]);
dif[zb]-=zc;
ans+=get(dif[zb]);
}
printf("%lld\n",ans);
}
}
10.9 顾z校内互坑题的更多相关文章
- 【BZOJ-1952】城市规划 [坑题] 仙人掌DP + 最大点权独立集(改)
1952: [Sdoi2010]城市规划 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 73 Solved: 23[Submit][Status][ ...
- 首师大附中互测题:LJX的校园:入学典礼【C003】
[C003]LJX的校园:入学典礼[难度C]—————————————————————————————————————————————————————————————————————————————— ...
- 升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了Failed to locate Homebrew!
升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了,用命令 sudo gem install cocoapod 装不上,换 sudo gem install -n/u ...
- hdu 5455 Fang Fang 坑题
Fang Fang Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5455 ...
- String类面试坑题
1.面试坑题F:\SHJT\JavaWorkspace\JavaSE\workspace\day13ezra\src\cn\itcast\sh\classcode\BTStringLastIndexO ...
- 2016 10 26考试 NOIP模拟赛 杂题
Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...
- UVaLive 7503 Change (坑题。。。。。。)
题意:给定两个人民币,问你花最少钱保证能够凑出另一个价格. 析:这个题最大的坑就是在,并一定是一次就凑出来,可以多次,然后就可以想了,如果要凑的数和1有关,特判,如果是2倍数,0.01就够了,否则就是 ...
- POJ-2387Til the Cows Come Home,最短路坑题,dijkstra+队列优化
Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K http://poj.org/problem?id=238 ...
- FZU- Problem 1147 Tiling,递推坑题,大数水过~~
Problem 1147 Tiling Time Limit: 1000 mSec Memory Limit : 32768 KB http://acm.fzu.edu.cn/problem.php? ...
随机推荐
- BInder浅析
Binder是什么 Binder是运行在Android内核态用于进程间通信(IPC)的驱动,采用C/S架构,由三项基本组件组成:Binder服务端,Binder驱动,应用程序客户端. 为什么要用Bin ...
- QA面试题:之一(中英文题目、难度:简单)
QA面试题:之一(中英文题目.难度:简单)
- selenium启动IE浏览器报错:selenium.common.exceptions.WebDriverException: Message: Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones. Enable Protected Mode mu
意思是浏览器的保护模式设置不一致所导致 解决方案-->修改IE设置 将所有区域的保护模式勾选去掉即可
- crontab-用于设置周期性被执行的指令
一个很好用的工具. 参考文章: [入门] http://baike.baidu.com/view/1229061.htm [进阶] http://blog.csdn.net/tianlesoftwar ...
- php中各种操作字符串和时间戳的代码关键词
<?php/** * Created by 郭鹏. * User: msi * Date: 2017/9/27 * Time: 14:17 */ //随机数生成器echo rand();echo ...
- android之SlideMenu双向滑动
开始动手之前先来讲一下实现原理,在一个Activity的布局中需要有三部分,一个是左侧菜单的布局,一个是右侧菜单的布局,一个是内容布局.左侧菜单居屏幕左边缘对齐,右侧菜单居屏幕右边缘对齐,然后内容布局 ...
- Tensorflow 载入数据的三种方式
Tensorflow 数据读取有三种方式: Preloaded data: 预加载数据 Feeding: Python产生数据,再把数据喂给后端. Reading from file: 从文件中直接读 ...
- joyOI 选课 【树形dp + 背包dp】
题目链接 选课 题解 基础背包树形dp #include<iostream> #include<cstdio> #include<cmath> #include&l ...
- 遍历Collection集合中的6种方法:
下面的代码演示了遍历Collection集合的6种方法,注意Collection集合的遍历远不止于增强for循环,和迭代器两种. 代码如下: package com.qls.traverse; imp ...
- Windows7下的Run运行命令一览表
按住Windows键(就是左边Ctrl和Alt之间那个印windows徽标的键,简称Win键)+R,即可弹出运行对话框,在里面输入黑体字符即可运行相应程序.相比XP这次新增了不少新东西. 添加/删除程 ...