4237. 【五校联考5day1】Melancholy (Standard IO)

题面:

DX3906星系,Melancholy星上,我在勘测这里的地质情况。
我把这些天来已探测到的区域分为N组,并用二元组(D,V)对每一组进行标记:其中D为区域的相对距离,V为内部地质元素的相对丰富程度。
在我的日程安排表上有Q项指派的计划。每项计划的形式是类似的,都是“对相对距离D在[L,R]之间的区域进行进一步的勘测,并在其中有次序地挑出K块区域的样本进行研究。”采集这K块的样品后,接下来在实验中,它们的研究价值即为这K块区域地质相对丰富程度V的乘积。
我对这Q项计划都进行了评估:一项计划的评估值P为所有可能选取情况的研究价值之和。
但是由于仪器的原因,在一次勘测中,这其中V最小的区域永远不会被选取。
现在我只想知道这Q项计划的评估值对2^32取模后的值,特殊地,如果没有K块区域可供选择,评估值为0。

样例

5 3

5 4 7 2 6

1 4 5 3 2

6 7 1

2 6 2

1 8 3

数据约束

5c4f099a25a9f.png

题目大意

给你一个序列,每次询问一个区间 \(l...r\) , 问从中选出K个数(除其中最小值)的所有组合的价值和(所选数的乘积)。

考场思路

先对D值进行排序,这样每次实质询问区间 $ L,R $ 都可以通过二分来确定;
在考虑如何统计答案。

先不考虑不能选区间中最小值的限制,考虑不算或者减去。
观察到K的值较小,我们联想到几种大体思路:

1.合并两区间答案。假设我已经求出了区间\(l , m\) 和 $ m + 1 , r$ 的 较小的K的答案,显然可合并答案求出大K的答案。

2.容斥(此处不详讲)。

考虑到区间查询以及 \(n\) 的 规模,我们采用线段树。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define R register 

using namespace std;

const int N = 1e5 + 10;
inline void read(int &x)
{
    x = 0;char c = getchar();
    while(c > '9' || c < '0') c = getchar();
    while(c >= '0' && c <= '9') x = x * 10 + c - '0' , c = getchar();
}

int n , q , tmp[N];
unsigned fact[10]; 

struct SGT
{
    unsigned val[6] , mi , po;
    void clear(){memset(val , 0 , sizeof val) , mi = 0x3f3f3f3f , po = 0;}
}g[N * 25];

SGT merge(SGT a ,SGT b)
{
    SGT ret;ret.clear();
    (a.mi < b.mi) && (ret.mi = a.mi , ret.po = a.po , 1) || (ret.mi = b.mi , ret.po = b.po);
        
    for(R int i = 1;i <= 6;i ++)
    {
        ret.val[i - 1] = a.val[i - 1] + b.val[i - 1];
        for(R int j = 1;j < i;j ++)
            ret.val[i - 1] += a.val[j - 1] * b.val[i - j - 1];  
    }
    return ret;     
}

struct note
{
    int D , V;
}rec[N];
int cmp(note a, note b){return a.D < b.D;}

void pre()
{
    for(R int i = fact[0] = 1;i <= n;fact[i] = fact[i - 1] *  i ,i ++);
}

void build(int l , int r ,int k)
{
    if(l == r) return(void)(g[k].val[0] = g[k].mi = rec[l].V , g[k].po = l);
    int mid = l + r >> 1;
    build(l , mid , k << 1) , build(mid + 1 , r , k << 1 | 1) , g[k] = merge(g[k << 1] , g[k << 1 | 1]);
}

void qry(int l , int r,int k,int _l,int _r,int tar ,SGT &x)
{
    if(l >= _l && r <= _r) return (void) (x = merge(x , g[k]));
    int mid = l + r >> 1;
    if(_l <= mid) qry(l , mid , k << 1 , _l , _r , tar , x);
    if(_r > mid) qry(mid + 1 , r, k << 1 | 1, _l , _r , tar , x);
}

unsigned done(int l, int r , int K)
{
    l = lower_bound(tmp + 1 , tmp + 1 + n , l) - tmp, r = upper_bound(tmp + 1 , tmp + 1 + n , r) - tmp - 1;
    if(r - l < K) return 0;
    SGT t , ret1 , ret2;ret1.clear() , ret2.clear() , t.clear();
    
    qry(1 , n , 1 , l , r , K , t);
    if(l < t.po) qry(1 , n , 1 , l , t.po - 1 , K, ret1);
    if(r > t.po) qry(1 , n , 1 , t.po + 1 , r , K , ret2);
        
    ret1 = merge(ret1 , ret2);
    return ret1.val[K - 1] * fact[K];
}

int main()
{
    read(n) , read(q);
    for(R int i = 1;i <= n;i ++) read(rec[i].D);
    for(R int i = 1;i <= n;i ++) read(rec[i].V);
    sort(rec + 1 , rec + 1 + n ,cmp) , pre();
    for(R int i = 1;i <= n;i ++) tmp[i] = rec[i].D;

    build(1 , n , 1);

    for(int l , r , K; q ; q --)
        read(l ) , read(r) , read(K),
        printf("%u\n",done(l , r , K));
    return 0;
}

别忘记隔绝最小值所参与的运算。
(因为取模数比较特别,可以利用 \(unsigned int\) 的自然溢出,减小高频取模的问题。)

转载于:https://www.cnblogs.com/Sin-demon/p/10332018.html

以下是截至2021年10月的全球动漫评分排行榜前100名: 1.《Fullmetal Alchemist: Brotherhood》 2.《Steins;Gate》 3.《Your Lie in April》 4.《Hunter x Hunter (2011)》 5.《Gintama》 6.《Haikyuu!!》 7.《Attack on Titan》 8.《Code Geass: Lelouch of the Rebellion》 9.《Clannad: After Story》 10.《Death Note》 11.《One Punch Man》 12.《Jojo's Bizarre Adventure》 13.《Cowboy Bebop》 14.《Baccano!》 15.《Neon Genesis Evangelion》 16.《Spirited Away》 17.《Monogatari Series》 18.《Shigatsu wa Kimi no Uso》 19.《Toradora!》 20.《Tengen Toppa Gurren Lagann》 21.《K-On!》 22.《The Melancholy of Haruhi Suzumiya》 23.《Fate/Zero》 24.《One Piece》 25.《Rurouni Kenshin: Trust and Betrayal》 26.《Dragon Ball Z》 27.《Legend of the Galactic Heroes》 28.《Hajime no Ippo》 29.《Ghost in the Shell: Stand Alone Complex》 30.《Nana》 31.《Samurai Champloo》 32.《Great Teacher Onizuka》 33.《Anohana: The Flower We Saw That Day》 34.《Kimi no Na wa.》 35.《Kara no Kyoukai》 36.《Psycho-Pass》 37.《Bakemonogatari》 38.《No Game No Life》 39.《Nichijou》 40.《Usagi Drop》 41.《Kill la Kill》 42.《Akira》 43.《Durarara!!》 44.《Tatami Galaxy》 45.《Katanagatari》 46.《Berserk》 47.《Princess Mononoke》 48.《Higurashi no Naku Koro ni》 49.《Soul Eater》 50.《Black Lagoon》 51.《Naruto》 52.《Fairy Tail》 53.《Kimi ni Todoke》 54.《Serial Experiments Lain》 55.《Kuroko no Basket》 56.《Chihayafuru》 57.《Hyouka》 58.《Bleach》 59.《Sakamichi no Apollon》 60.《Golden Time》 61.《Love Live! School Idol Project》 62.《Cardcaptor Sakura》 63.《Gekkan Shoujo Nozaki-kun》 64.《Full Metal Panic!》 65.《Mobile Suit Gundam: Iron-Blooded Orphans》 66.《K-On! Movie》 67.《Kizumonogatari》 68.《Re:Zero kara Hajimeru Isekai Seikatsu》 69.《Shirobako》 70.《Yahari Ore no Seishun Love Comedy wa Machigatteiru.》 71.《Darker than Black》 72.《Honey and Clover》 73.《Zankyou no Terror》 74.《Usagi Drop Specials》 75.《Mahou Shoujo Madoka★Magica》 76.《Bungou Stray Dogs》 77.《Kara no Kyoukai 5: Mujun Rasen》 78.《K-On! 2》 79.《Toaru Kagaku no Railgun》 80.《Kimi ga Nozomu Eien》 81.《Grisaia no Kajitsu》 82.《Gochuumon wa Usagi Desu ka?》 83.《Shinsekai yori》 84.《Nodame Cantabile》 85.《Bungou Stray Dogs 2nd Season》 86.《Made in Abyss》 87.《Gin no Saji》 88.《Ranma ½》 89.《K-On!!》 90.《Sword Art Online》 91.《Hibike! Euphonium》 92.《Nisekoi》 93.《K-On!: Live House!》 94.《K-On!: Keikaku!》 95.《D-Frag!》 96.《K-On!: Ura-ON!》 97.《K-On!: College》 98.《K-On!: Fude Pen - Boru Pen》 99.《K-On!: Plan!》 100.《K-On!: Movie - Wonderful♪》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值