湖南集训day5
难度:☆☆☆☆☆☆☆



/*
二分答案
算斜率算截距巴拉巴拉很好推的公式
貌似没这么麻烦我太弱了......
唉不重要...
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> #define N 100007 using namespace std;
int n,m,cnt;
int X[N],Y[N];
double k,x,y,b,dis2;
struct segment
{
double k,b;
}e[N<<]; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} double work(double x,double y)
{
return sqrt(double(x)*double(x)+double(y)*double(y));
} int main()
{
freopen("geometry.in","r",stdin);
freopen("geometry.out","w",stdout);
n=read();
for(int i=;i<=n;i++) X[i]=read();
for(int i=;i<=n;i++) Y[i]=read();
sort(X+,X+n+);sort(Y+,Y+n+);
for(int i=;i<=n;i++)
{
e[i].k=double(Y[i])/-double(X[i]);
e[i].b=Y[i];
}
m=read();
for(int i=;i<=m;i++)
{
x=read();y=read();cnt=;
if(x==)
{
int l=,r=n,mid;
while(l<=r)
{
mid=l+r>>;
if(Y[mid]>=y) cnt=mid,l=mid+;
else r=mid-;
}
}
double dis1=work(double(x),double(y));
k=double(y)/double(x);
int l=,r=n,mid;
while(l<=r)
{
mid=l+r>>;
if(work(double(e[mid].b/(k-e[mid].k)),k*double(e[mid].b/(k-e[mid].k)))<=dis1)
cnt=mid,l=mid+;
else r=mid-;
}
printf("%d\n",cnt);
}
fclose(stdin);fclose(stdout);
return ;
}



/*
貌似数据水,贪心能贪70分...
差分约束做法
记录前缀和S[i],i>=8时首先要满足条件 s[i]-s[i-8]>=a[i]
0<=s[i]-s[i-1]<=b[i]
当i<8时有s[23]-s[16+i]+s[i]>=a[i]
因为第三个式子不满足差分约束形式,可以看出s[23]有单调性,可以二分…所以可以二分答案当常量处理
Spfa负环则无解
还有一种网络流做法,表示很懵逼。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> #define N 33 using namespace std;
int n,m,ans,cnt;
int head[N<<],dis[N],a[N],b[N];
bool inq[N];
struct edge{
int u,v,dis,net;
}e[N<<]; inline void add(int u,int v,int w)
{
e[++cnt].v=v;e[cnt].net=head[u];e[cnt].dis=w;head[u]=cnt;
} inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} bool spfa()
{
queue<int>q;
memset(dis,-0x7f7f7f,sizeof dis);
memset(inq,,sizeof inq);
dis[]=;inq[]=;q.push();
while(!q.empty())
{
int u=q.front();q.pop();inq[u]=;
if(dis[u]>) return false;
for(int i=head[u];i;i=e[i].net)
{
int v=e[i].v;
if(dis[v]<dis[u]+e[i].dis)
{
dis[v]=dis[u]+e[i].dis;
if(!inq[v]) inq[v]=,q.push(v);
}
}
}return true;
} bool solve(int ans)
{
memset(head,,sizeof head);
cnt=;
for(int i=;i<=;i++) add(i-,i,a[i]);
for(int i=;i<=;i++) add(i+,i,a[i]- ans);
for(int i=;i<=;i++) add(i-,i,);
for(int i=;i<=;i++) add(i,i-,-b[i]);
add(,,ans);add(,,-ans);
return spfa();
} int main()
{
freopen("cashier.in","r",stdin);
freopen("cashier.out","w",stdout);
n=read();
while(n--)
{
for(int i=;i<=;i++) a[i]=read();
for(int i=;i<=;i++) b[i]=read();
ans=;
while()
{
if(++ans>)
{
ans=-;break;
}
if(solve(ans)) break;
}
printf("%d\n",ans);
}
return ;
}





线段树
部分分可以dp f[i][j]表示前i个数选了j个的答案
f[i][j]=f[i-1][j]+f[i-1][j-1]*a[i] (i选不选)
k=1时线段树区间求和区间修改,我只会这个....
线段树区间合并操作。
k比较小,所以线段树每个节点维护一个区间答案记为f[i]
考虑一段区间i,左边取j个右边就取i-j个 答案是每个方案的左边乘右边的和。
就是i左儿子f[j]和右边的f[i-j] 所以f[i]=Σ(j=0~i) lc f[j]*rc f[i-j]
考虑取反操作,i是奇数就取反,偶数无影响(因为是相乘)
考虑区间加, 开始f[i] 是 a1*a2……an 后来是(a1+c)*(a2+c)……(an+c)
考虑类似二项式定理,当上述a1~an n个方案如果取了j个了,分别为al1,al2……alj
那考虑最后答案,如果已经选了j个方案是(al1+c)(al2+c)……(alj+c)再还能选i-j个 最后答案是C(len-i,i-j)*f[j]*c^(i-j)
复杂度 O(k^2*nlogn)
只懂思路,代码....果断粘std
#include <cstdio>
#include <cstdlib>
#define MOD 1000000007
#define N 100005
typedef long long LL;
using namespace std;
struct Node
{
LL f[11];
} node[N * 4];
LL a[N], lazy1[N * 4];
bool lazy2[N * 4];
LL C[N][11]; Node merge(Node lc, Node rc)
{
Node o;
o.f[0] = 1;
for (int i = 1; i <= 10; i++)
{
o.f[i] = 0;
for (int j = 0; j <= i; j++)
o.f[i] = (o.f[i] + lc.f[j] * rc.f[i - j] % MOD) % MOD;
}
return o;
} void build(int o, int l, int r)
{
if (l == r)
{
for (int i = 0; i <= 10; i++) node[o].f[i] = 0;
node[o].f[0] = 1;
node[o].f[1] = (a[l] % MOD + MOD) % MOD;
return ;
}
int mid = (l + r) >> 1;
build(o * 2, l, mid);
build(o * 2 + 1, mid + 1, r);
node[o] = merge(node[o * 2], node[o * 2 + 1]);
return ;
} void update1(int o, int l, int r, int c)
{
int len = r - l + 1;
LL ff[11];
for (int i = 0; i <= 10; i++) ff[i] = node[o].f[i];
for (int i = 1; i <= 10; i++)
{
node[o].f[i] = 0;
LL t = 1;
for (int j = 0; j <= i; j++)
{
LL tmp = ff[i - j] * C[len - (i - j)][j] % MOD * t % MOD;
node[o].f[i] = (node[o].f[i] + tmp) % MOD;
t = t * c % MOD;
}
}
return ;
} void push_down(int o, int l, int r)
{
int mid = (l + r) >> 1;
if (lazy1[o])
{
if (lazy2[o * 2])
lazy1[o * 2] = (lazy1[o * 2] + MOD - lazy1[o]) % MOD;
else
lazy1[o * 2] = (lazy1[o * 2] + lazy1[o]) % MOD;
if (lazy2[o * 2 + 1])
lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + MOD - lazy1[o]) % MOD;
else
lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + lazy1[o]) % MOD;
update1(o * 2, l, mid, lazy1[o]);
update1(o * 2 + 1, mid + 1, r, lazy1[o]);
lazy1[o] = 0;
}
if (lazy2[o])
{
lazy2[o * 2] ^= 1;
lazy2[o * 2 + 1] ^= 1;
for (int j = 1; j <= 10; j += 2)
{
node[o * 2].f[j] = MOD - node[o * 2].f[j];
node[o * 2 + 1].f[j] = MOD - node[o * 2 + 1].f[j];
}
lazy2[o] = 0;
}
} void modify1(int o, int l, int r, int ll, int rr, int c)
{
if (ll <= l && rr >= r)
{
if (lazy2[o]) lazy1[o] = (lazy1[o] + MOD - c) % MOD;
else lazy1[o] = (lazy1[o] + c) % MOD;
update1(o, l, r, c);
return ;
}
int mid = (l + r) >> 1;
push_down(o, l, r);
if (ll <= mid) modify1(o * 2, l, mid, ll, rr, c);
if (rr > mid) modify1(o * 2 + 1, mid + 1, r, ll, rr, c);
node[o] = merge(node[o * 2], node[o * 2 + 1]);
return ;
} void modify2(int o, int l, int r, int ll, int rr)
{
if (ll <= l && rr >= r)
{
for (int i = 1; i <= 10; i += 2) node[o].f[i] = MOD - node[o].f[i];
lazy2[o] ^= 1;
return ;
}
int mid = (l + r) >> 1;
push_down(o, l, r);
if (ll <= mid) modify2(o * 2, l, mid, ll, rr);
if (rr > mid) modify2(o * 2 + 1, mid + 1, r, ll, rr);
node[o] = merge(node[o * 2], node[o * 2 + 1]);
return ;
} Node query(int o, int l, int r, int ll, int rr)
{
if (ll <= l && rr >= r)
return node[o];
int mid = (l + r) >> 1;
push_down(o, l, r);
if (rr <= mid) return query(o * 2, l, mid, ll, rr);
if (ll > mid) return query(o * 2 + 1, mid + 1, r, ll, rr);
Node lc = query(o * 2, l, mid, ll, rr);
Node rc = query(o * 2 + 1, mid + 1, r, ll, rr);
return merge(lc, rc);
} int main(int argc, char ** argv)
{
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
int n, m;
scanf("%d %d", &n, &m);
C[0][0] = 1;
for (int i = 1; i <= n; i++)
{
C[i][0] = 1;
for (int j = 1; j <= 10; j++)
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
}
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
build(1, 1, n);
for (int i = 1; i <= m; i++)
{ int l, r, opt;
scanf("%d%d%d",&opt, &l, &r);
if (opt == 1)
{
int c;
scanf("%d", &c);
c = (c % MOD + MOD) % MOD;
modify1(1, 1, n, l, r, c);
}
else if (opt == 2)
{
modify2(1, 1, n, l, r);
}
else
{
int k;
scanf("%d", &k);
Node o = query(1, 1, n, l, r);
printf("%d\n", o.f[k] % MOD);
}
}
return 0;
}
湖南集训day5的更多相关文章
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- 「2017 山东一轮集训 Day5」苹果树
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...
- 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生
题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...
- P3900 [湖南集训]图样图森破
P3900 [湖南集训]图样图森破 链接 分析: 感觉像个暴力. 可以枚举回文串的回文中心,即枚举一个串,枚举一个串的位置作为回文中心,然后求出这个串内的回文串的长度. 此时如果回文串两端都没有到这个 ...
- 2019暑期金华集训 Day5 树上数据结构
自闭集训 Day5 树上数据结构 前置知识 点分治 边分治 树链剖分 LCT Top Tree LCT时间复杂度 线段树每次查询是严格\(\log n\)的,然而splay维护连续段的时候,如果每次查 ...
- 2019暑期金华集训 Day5 生成函数
自闭集训 Day5 生成函数 一般生成函数 无脑地把序列变成多项式: \[ \{a_i\}\rightarrow A(x)=\sum_{n} a_nx^n \] 形式幂级数 生成函数是一种形式幂级数. ...
- 杭州集训Day5
下面是Day5的题目!(其实都咕了好几天了 100+70+40=210. T1 皇后 XY 的疑难 (1s 512MB) 1.1 题目描述 有一个n*n的王国城堡地图上,皇后XY喜欢看骑士之间的战斗, ...
- 「疫期集训day5」火焰
我们就像一把穿刺敌人的利刃,把敌人开肠破肚----凡尔登高地前气势汹汹的德军 今天没有考试,挺好,有时间自己做题了 今天主要复习+学习了数据结构,列了个表: 已完成:单调队列,线段树,set/vect ...
- 2022寒假集训day5
day5 五道栈的题加上字符串. 单调队列. T1 表达式括号匹配 洛谷P1739 题目描述 假设一个表达式有英文字母(小写).运算符(+,-,*,/)和左右小(圆)括号构成,以"@&q ...
随机推荐
- 浅谈AC自动机模板
什么是AC自动机? 百度百科 Aho-Corasick automaton,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法. 要学会AC自动机,我们必须知道什么是Trie,也就是字典树.Tr ...
- python 爬取微信好友列表和个性签名,绘制个性签名云图
python爬取微信好友列表和个性签名,绘制个性签名云图 1. 简要介绍 本次实验主要用到下面几个库 : 1)itchat---用于微信接口,实现生成QR码,用于微信扫描登陆 2)re(正则化)--- ...
- idea14远程调试linux下的tomcat
进入到idea的tomcat的run/debug配置,新建个remote tomcat,然后填写相关信息,如上图(注意远程调试端口). 再选择Startup/Connection,如下图所示: 到此, ...
- 第八节:web爬虫之urllib(四)
第三个 模块parse : 是一个工具模块,提供了许多 URL 处理方法,比如拆分.解析.合并等等的方法.
- Jet --theory
(FIG. 6. A caricature of turbulent jet and the entrainment., Jimmy, 2012) Ref: Jimmy Philip, Phys. F ...
- wannafly-day1 Problem B-Board
思路:这个题队友过的,我的思路是枚举行和列,将除了要求位置初始0,每行最小值相减,每列最小值相减,直到除了要求的位置,别的位置都为零,则那个位置取绝对值就行了,有点麻烦应该能过,但是他没有用我给的想法 ...
- 2.6 访问 Shell 脚本的参数
所谓的位置参数(positional parameters)指的也就是Shell脚本的命令行参数(command-line arguments).在Shell函数里,它们同时也可以是函数的参数 ...
- Python基础(五)集合与函数
一.Set集合 set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key.下面一起看一下set的定义和使用方法: (一),set定义 1 ...
- Leetcode 131.分割回文串
分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa" ...
- HBase连接数据库(集群)
一.使用java接口对hbase进行表的创建1.引入需要的jar包2.代码: public static void main(String[] args) throws Exception { //得 ...