coderforces 138CMushroom Gnomes - 2线段树

点击打开链接

题意:给定n个树,和m个人,接下来n行是每个树的位置,高度,向左倒的概率,向右倒的概率,接下来给出m个人的位置,判断每个人活下来的概率乘上Zi然后相加。

思路:涌用线段树的节点维护概率,先进行离散化,本来的话可能应该用到成段更新,但这题可以避免,下面会给出注释。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=100010;
double num[2000010];//离散化后的点可能会变多了2倍
vector G;
map pp;
void buildtree(int le,int ri,int node){
    num[node]=1;
    if(le==ri) return ;
    int t=(le+ri)>>1;
    buildtree(le,t,node<<1);
    buildtree(t+1,ri,node<<1|1);
}
void update(int l,int r,double add,int le,int ri,int node){
    if(l<=le&&ri<=r){
        num[node]*=add;
        return ;
    }
    int t=(le+ri)>>1;
    if(l<=t) update(l,r,add,le,t,node<<1);
    if(r>t) update(l,r,add,t+1,ri,node<<1|1);
}
double query(int pos,int le,int ri,int node){
    if(le==ri) return num[node];
    int t=(le+ri)>>1;
    if(pos<=t) return num[node]*query(pos,le,t,node<<1);//因为这里返回的是概率相乘,相当于已经更新,和懒惰标记思想差不多
    else return num[node]*query(pos,t+1,ri,node<<1|1);
}
int main(){
    int L[maxn],R[maxn],X[maxn],H[maxn],P[10010],n,m,B[10010];
    while(scanf("%d%d",&n,&m)!=-1){
        G.clear();
        for(int i=0;i

你可能感兴趣的:(ACM,数据结构,线段树,CF,线段树&树状数组,线段树)