zoukankan      html  css  js  c++  java
  • 线段树(种树)

                                                                                                                     2017种树

    题目描述

    2017共有N棵树从0到N-1标号。现要把这些树种在一条直线上,第i棵树的种植位置X[i]如下确定:

    X[0] = X[0] MOD L;

    X[i] = (X[i-1]*A+B) MOD L。

    每棵树种植的费用,是所有标号比它小的树与它的距离之和。2017请你计算各棵树的费用之积,最后对1000000007取余。

    输入格式

    共五行:

    第一行为N

    第二行为L

    第三行为X[0]

    第四行为A

    第五行为B

    输出格式

    总费用

    样例

    样例输入

    5
    10
    3
    1
    1
    

    样例输出

    180
    

    样例解释:

    5棵树的位置分别为: 3, 4, 5, 6, 7.

    费用分别为: 1, 3, 6, 10. (从第一棵树开始)

    总费用为: 1 × 3 × 6 × 10 = 180.

    数据范围与提示

    10%的数据:N<=10;

    60%的数据:N<=2×10^5;

    100%的数据:N,L<=200000; X[0] ,A, B<=10^9.

    思路:

    思路:用线段树维护的数x小的个数以及比x(第i个数的位置)小的数的和,比x大的树的个数以及比x大的数的和,x的费==(x×比x小的数的个数-比x小的数的和)+(比x大的数的和-x×比x大的数的个数)。

     1 #include<cstdio>
     2 const int maxn=200000+10,mod=1000000007;
     3 int tree[maxn<<2],cnt[maxn<<2];
     4 int n,l,xx,a,b;
     5 int ans=1;
     6 void Build(int rt,int l,int r){
     7     if(l==xx&&r==xx){
     8         tree[rt]+=xx;
     9         cnt[rt]++;
    10         return ;
    11     }
    12     int mid=(l+r)>>1;
    13     if(xx<=mid) Build(rt<<1,l,mid);
    14     else Build(rt<<1|1,mid+1,r);
    15     tree[rt]=(tree[rt<<1]+tree[rt<<1|1])%mod;
    16     cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
    17 }
    18 int query(int rt,int l,int r,int s,int t){
    19     if(s<l) s=l;
    20     if(t>r) t=r;
    21     if(s==l&&t==r){
    22         return tree[rt];
    23     }
    24     int mid=(l+r)>>1;
    25     if(t<=mid) return query(rt<<1,l,mid,s,t)%mod;
    26     else if(s>mid) return query(rt<<1|1,mid+1,r,s,t)%mod;
    27     else return (query(rt<<1,l,mid,s,t)+query(rt<<1|1,mid+1,r,s,t))%mod;
    28 }
    29 int query1(int rt,int l,int r,int s,int t){
    30     if(s<l) s=l;
    31     if(t>r) t=r;
    32     if(s==l&&t==r) return cnt[rt];
    33     int mid=(l+r)>>1;
    34     if(t<=mid) return query1(rt<<1,l,mid,s,t)%mod;
    35     else if(s>mid) return query1(rt<<1|1,mid+1,r,s,t)%mod;
    36     else return (query1(rt<<1,l,mid,s,t)+query1(rt<<1|1,mid+1,r,s,t))%mod;
    37 }
    38 void Modify(int rt,int l,int r,int w){
    39     if(l==w&&r==w){
    40         tree[rt]+=w;
    41         cnt[rt]++;
    42         return ;
    43     }
    44     int mid=(l+r)>>1;
    45     if(w<=mid) Modify(rt<<1,l,mid,w);
    46     else Modify(rt<<1|1,mid+1,r,w);
    47     tree[rt]=(tree[rt<<1]+tree[rt<<1|1])%mod;
    48     cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
    49 }
    50 void solve(int x){
    51     int Min_sum=query(1,0,l-1,0,x);
    52     int Min_cnt=query1(1,0,l-1,0,x);
    53     int Max_sum=query(1,0,l-1,x,l-1);
    54     int Max_cnt=query1(1,0,l-1,x,l-1);
    55     int sum=((Min_cnt*x)%mod-Min_sum%mod+Max_sum%mod-(Max_cnt*x)%mod)%mod;
    56     ans=(ans*sum)%mod;
    57     Modify(1,0,l-1,x);
    58 }
    59 int main(){
    60     scanf("%d%d%d%d%d",&n,&l,&xx,&a,&b);    
    61     xx=xx%l;
    62     Build(1,0,l-1);
    63     for(int i=1;i<n;i++){
    64         int x;
    65         x=(xx*a+b)%mod;
    66         solve(x);
    67         xx=x;
    68     }
    69     printf("%d
    ",ans);
    70     return 0;
    71 }
    View Code

  • 相关阅读:
    POJ-1088 滑雪 (包含部分自用测试数据)
    PHP-从零开始使用Solr搜索引擎服务(下)
    PHP-从零开始使用Solr搜索引擎服务(上)
    15位身份证号转化为18位身份证号
    php的数组转为对象
    H5页面遮罩弹框下层还能滚动的问题
    纯css实现长宽等比例的div
    VUE开发一个图片轮播的组件
    jQuery map和each用法
    表格式布局让每个列高度等于该行最大高度
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13301161.html
Copyright © 2011-2022 走看看