湖南集训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 ...
随机推荐
- <SpringMvc>入门七 拦截器
什么是拦截器 1.SpringMVC框架中的拦截器用于 对处理器 进行预处理和后处理的技术. 2.可以定义拦截器链,按照顺序执行. 3.拦截器和过滤器功能类似,区别在 拦截器 过滤器 过滤器是Serv ...
- Centos7二进制文件安装MySQL5.7.25
1.删除centos系统自带的mariadb数据库防止发生冲突 rpm -qa|grep mariadb rpm -e mariadb-libs --nodeps 2.安装libaio库 yum -y ...
- python re模块与正则
1. re模块 1.1 转义符 正则表达式中的转义符在python的字符串中也刚好有转移的作用,但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突. 为了避免这种冲突,我们所有的正则都 ...
- 原生js实现三个按钮绑定三个计时器,点击其中一个按钮,开启当前计时器,另外另个不开启
今天在某个前端交流群,有个小伙伴问了一个小功能,自己想了一下,代码如下,可以实现基本功能: 下面是html结构 <div id="demo"> <input ty ...
- 洛谷 1937 [USACO10MAR]仓配置Barn Allocation
[题解] 贪心. 把区间按照右端点从小到大排序,右端点相同的按照长度从小到大排序,然后按顺序考虑,能放就放下去. 维护能不能放下去用线段树即可. #include<cstdio> #inc ...
- https://gitee.com/tomsun28/bootshiro-------需要研究的项目
https://gitee.com/tomsun28/bootshiro-------需要研究的项目
- [luoguP2904] [USACO08MAR]跨河River Crossing(DP)
传送门 f[i] 表示送前 i 头牛过去再回来的最短时间 f[i] = min(f[i], f[j] + sum[i - j] + m) (0 <= j < i) ——代码 #includ ...
- Codeforces Round #260 (Div. 2) D
D. A Lot of Games time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- cogs——908. 校园网
908. 校园网 ★★ 输入文件:schlnet.in 输出文件:schlnet.out 简单对比 时间限制:1 s 内存限制:128 MB USACO/schlnet(译 by Fe ...
- react-浏览后的想法