难度:☆☆☆☆☆☆☆

/*
二分答案
算斜率算截距巴拉巴拉很好推的公式
貌似没这么麻烦我太弱了......
唉不重要...
*/
#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的更多相关文章

  1. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  2. 「2017 山东一轮集训 Day5」苹果树

    「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...

  3. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  4. P3900 [湖南集训]图样图森破

    P3900 [湖南集训]图样图森破 链接 分析: 感觉像个暴力. 可以枚举回文串的回文中心,即枚举一个串,枚举一个串的位置作为回文中心,然后求出这个串内的回文串的长度. 此时如果回文串两端都没有到这个 ...

  5. 2019暑期金华集训 Day5 树上数据结构

    自闭集训 Day5 树上数据结构 前置知识 点分治 边分治 树链剖分 LCT Top Tree LCT时间复杂度 线段树每次查询是严格\(\log n\)的,然而splay维护连续段的时候,如果每次查 ...

  6. 2019暑期金华集训 Day5 生成函数

    自闭集训 Day5 生成函数 一般生成函数 无脑地把序列变成多项式: \[ \{a_i\}\rightarrow A(x)=\sum_{n} a_nx^n \] 形式幂级数 生成函数是一种形式幂级数. ...

  7. 杭州集训Day5

    下面是Day5的题目!(其实都咕了好几天了 100+70+40=210. T1 皇后 XY 的疑难 (1s 512MB) 1.1 题目描述 有一个n*n的王国城堡地图上,皇后XY喜欢看骑士之间的战斗, ...

  8. 「疫期集训day5」火焰

    我们就像一把穿刺敌人的利刃,把敌人开肠破肚----凡尔登高地前气势汹汹的德军 今天没有考试,挺好,有时间自己做题了 今天主要复习+学习了数据结构,列了个表: 已完成:单调队列,线段树,set/vect ...

  9. 2022寒假集训day5

    day5 五道栈的题加上字符串. 单调队列. T1 表达式括号匹配   洛谷P1739 题目描述 假设一个表达式有英文字母(小写).运算符(+,-,*,/)和左右小(圆)括号构成,以"@&q ...

随机推荐

  1. ie6,ie7,ie8,FF 浏览器兼容问题

    javascript部分 1. document.form.item 问题问题:代码中存在 document.formName.item("itemName") 这样的语句,不能在 ...

  2. 散列--P1047 校门外的树

    题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,-,L,都种有 ...

  3. 数组--P1980 计数问题

    题目描述 题解 试计算在区间 1 到 n的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1到 11中,即在 1,2,3,4,5,6,7,8,9,10,11 中,数字 1 出现了 ...

  4. 大理石在哪儿(Where is the Marble?,Uva 10474)

    现有N个大理石,每个大理石上写了一个非负整数.首先把各数从小到大排序,然后回 答Q个问题.每个问题问是否有一个大理石写着某个整数x,如果是,还要回答哪个大理石上 写着x.排序后的大理石从左到右编号为1 ...

  5. linux(Ubuntu16)下切换python2和python3(转)

    采用update-alternatives 切换版本 1.打开终端:Ctrl+Alt+T 2.查看update-alternatives的帮助信息:update-alternatives --help ...

  6. 55.fielddata内存控制以及circuit breaker断路器

    课程大纲 fielddata加载 fielddata内存限制 监控fielddata内存使用 circuit breaker 一.fielddata加载 fielddata加载到内存的过程是lazy加 ...

  7. Spring 4 整合RMI技术及发布多个服务(xjl456852原创)

    rmi需要建立两个项目,一个是服务端的项目,一个是客户端的项目.服务端项目启动后,再启动客户端项目去调用服务端的方法. 我们建立两个maven项目: pom.xml配置: <?xml versi ...

  8. ansible roles例子

    #理解 changed_when failed_when become become_user ansible_become ansible_become_user static #检查group_v ...

  9. mongodb local数据库的空间初始化好大啊!

    新建立了一个replicat set,登录到primary里,show dbs一看吓一跳 local数据库竟然占用了80多G的空间 [root@wxlab31 bin]# ./mongo --host ...

  10. [河南省队2012] 找第k小的数

    ★★☆   输入文件:kth.in   输出文件:kth.out   简单对比时间限制:1 s   内存限制:128 MB 题目描述 看到很短的题目会让人心情愉悦,所以给出一个长度为N的序列A1,A2 ...