zoukankan      html  css  js  c++  java
  • 绵阳东辰国际test.10.7eve

    咕咕咕(gugugu)

    【题目描述】

    有一个长度为N的数轴,数轴的范围从 1N 还有 M个区间,其中第i个区间是 [Li,Ri]并且有一个权值 Vi。定义一个选择区间的方案是合法的,当且仅当数轴上每一个整点都被至少一个区间覆盖了,同时该方案的权值是所有选择区间的权值乘积。

    ​ 请你求出所有合法方案权值的和。由于答案可能很大,请输出其对1e9+7取模的结果。

    【输入格式】

    第一行两个正整数 N,M 。

    ​ 接下来 M行,第 i 行先是两个正整数 Li,Ri描述区间,然后一个非负整数 Vi描述区间的权值。

    【输出格式】

    ​ 输出仅一行,表示答案对 1e9+7取模的结果。

    【数据范围】

    1<=N,M<=2e5+5,Vi<1e9+7

    蒟蒻分析:首先来个排序就nlogn,然后在On扫一遍得到答案,结果发现扫不来呀!

    蒟蒻总结:思维就陷进了出题人的圈套里,总是想怎么样组成方案,组成方案后答案怎么统计,结果正解根本不是这么想的,其实当时就明白了这样想是死路一条,但就是偏偏往里钻

    solution by jklover %%

    将所有区间按照左端点 Li从小到大排序后,

    f(i,j) 表示考虑了前 i 个区间,所有覆盖了 [1,j] 的方案的权值和.

    转移时,若不选第 i 个区间,则

    f(i,j)+=f(i−1,j)

    若选第 i个区间,则只能从 f(i−1,j)转移过来,否则

    f(i,max(j,Ri))+=vi⋅f(i−1,j),j≥Li−1

    利用线段树优化转移,时间复杂度 O(mlog⁡n).

    然后我搞忘区间乘法怎么pushdown了(先说下面这pushdown不是我写的,是不是觉得超级丑?)

    void pushdown(int root, int l, int r){
        int m=(l+r)/2;
    //根据我们规定的优先度,儿子的值=此刻儿子的值*爸爸的乘法lazytag+儿子的区间长度*爸爸的加法lazytag
        st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(m-l+1))%p;
        st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(r-m))%p;
    //很好维护的lazytag
        st[root*2].mul=(st[root*2].mul*st[root].mul)%p;
        st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p;
        st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p;
        st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p;
    //把父节点的值初始化
        st[root].mul=1;
        st[root].add=0;
        return ;
    }
    

    code by theshaow

    #include<bits/stdc++.h>
    #define del(a,i) memset(a,i,sizeof(a))
    #define ll long long
    #define inl inline
    #define il inl void
    #define it inl int
    #define ill inl ll
    #define re register
    #define ri re int
    #define rl re ll
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&(-x))
    #define mid ((l+r)>>1)
    using namespace std;
    namespace io {
    	const int SIZE = (1 << 21) + 1;
    	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
    	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
    	inline void flush () {
    		fwrite (obuf, 1, oS - obuf, stdout);
    		oS = obuf;
    	}
    	inline void putc (char x) {
    		*oS ++ = x;
    		if (oS == oT) flush ();
    	}
    	template <class I>
    	inline void read (I &x) {
    		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
    		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
    	}
    	template <class I>
    	inline void print (I x) {
    		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
    		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
    		while (qr) putc (qu[qr --]);
    	}
    	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
    }
    using io :: read;
    using io :: putc;
    using io :: print;
    const int MAXN = 2e5+5,mod = 1e9+7;
    int n,m,dp[MAXN],a[MAXN];
    struct Node{
    	int l,r,val;
    	bool operator <(const Node &t) const{
    		return l==t.l?r<t.r:l<t.l;
    	}
    }node[MAXN];
    inl bool cmp(Node x,Node y){
    	return x.l==y.l?x.r<y.r:x.l<y.l;
    }
    it add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    it mul(int x,int y){return 1ll*x*y%mod;}
    #define lc (cur<<1)
    #define rc (cur<<1|1)
    struct Seg_Tree{
    	int sum,tag_add,tag_mul;
    }T[MAXN<<2];
    il build(int cur,int l,int r){
    	T[cur].tag_mul=1;
    	if(l==r) return ;
    	build(lc,l,mid),build(rc,mid+1,r);
    }
    il pushup(int cur){T[cur].sum=add(T[lc].sum,T[rc].sum);}
    il pushdown(int cur,int l,int r){
    	if(!T[cur].tag_add&&T[cur].tag_mul==1) return ;
    	if(T[cur].tag_mul!=1){
    		T[lc].sum=mul(T[lc].sum,T[cur].tag_mul);
    		T[lc].tag_mul=mul(T[lc].tag_mul,T[cur].tag_mul);
    		T[lc].tag_add=mul(T[lc].tag_add,T[cur].tag_mul);
    		T[rc].sum=mul(T[rc].sum,T[cur].tag_mul);
    		T[rc].tag_mul=mul(T[rc].tag_mul,T[cur].tag_mul);
    		T[rc].tag_add=mul(T[rc].tag_add,T[cur].tag_mul);
    		T[cur].tag_mul=1;
    	}
    	if(T[cur].tag_add){
    		T[lc].sum=add(T[lc].sum,mul(T[cur].tag_add,mid-l+1));
    		T[lc].tag_add=add(T[lc].tag_add,T[cur].tag_add);
    		T[rc].sum=add(T[rc].sum,mul(T[cur].tag_add,r-mid));
    		T[rc].tag_add=add(T[rc].tag_add,T[cur].tag_add);
    		T[cur].tag_add=0;
    	}
    }
    il updata_add(int cur,int l,int r,int pos,int k){
    	if(l==r) return T[cur].tag_add=add(T[cur].tag_add,k),T[cur].sum=add(T[cur].sum,k),void();
    	pushdown(cur,l,r);
    	if(mid>=pos) updata_add(lc,l,mid,pos,k);
    	else updata_add(rc,mid+1,r,pos,k);
    	pushup(cur);
    }
    il updata_mul(int cur,int l,int r,int L,int R,int k){
    	if(l>=L&&r<=R) return T[cur].sum=mul(T[cur].sum,k),T[cur].tag_add=mul(T[cur].tag_add,k),T[cur].tag_mul=mul(T[cur].tag_mul,k),void();
    	pushdown(cur,l,r);
    	if(mid>=L) updata_mul(lc,l,mid,L,R,k);
    	if(R>mid) updata_mul(rc,mid+1,r,L,R,k);
    	pushup(cur);
    }
    it query(int cur,int l,int r,int L,int R){
    	if(l>=L&&r<=R) return T[cur].sum;
    	pushdown(cur,l,r);ri res=0;
    	if(mid>=L) res=add(res,query(lc,l,mid,L,R));
    	if(R>mid) res=add(res,query(rc,mid+1,r,L,R));
    	return res;
    }
    int main(){
    	freopen("gugugu.in","r",stdin);
    	freopen("gugugu.out","w",stdout);
    	read(n),read(m);
    	for(ri i=1;i<=m;++i) read(node[i].l),read(node[i].r),read(node[i].val);
    	sort(node+1,node+1+m,cmp);
    	if(node[1].l!=1) return puts("0"),0;
    	build(1,0,n),updata_add(1,0,n,0,1);
    	for(ri i=1;i<=m;++i){
    		ri res=query(1,0,n,node[i].l-1,node[i].r);
    		updata_add(1,0,n,node[i].r,mul(res,node[i].val));
    		updata_mul(1,0,n,node[i].r+1,n,node[i].val+1);
    	}
    	print(query(1,0,n,n,n));
    	return 0;
    }
    

    第二题gugu太简单了

    送分题就是出题人比较傻逼,没说条件能否成立,样例又没这种情况

    相信大家只要注意到了,这题都会A掉,不然就只有40分哦

    直接solution by jklover%%%%

    gugu

    code by theshadow

    #include<bits/stdc++.h>
    #define del(a,i) memset(a,i,sizeof(a))
    #define ll long long
    #define inl inline
    #define il inl void
    #define it inl int
    #define ill inl ll
    #define re register
    #define ri re int
    #define rl re ll
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&(-x))
    #define mid ((l+r)>>1)
    using namespace std;
    namespace io {
    	const int SIZE = (1 << 21) + 1;
    	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
    	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
    	inline void flush () {
    		fwrite (obuf, 1, oS - obuf, stdout);
    		oS = obuf;
    	}
    	inline void putc (char x) {
    		*oS ++ = x;
    		if (oS == oT) flush ();
    	}
    	template <class I>
    	inline void read (I &x) {
    		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
    		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
    	}
    	template <class I>
    	inline void print (I x) {
    		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
    		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
    		while (qr) putc (qu[qr --]);
    	}
    	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
    }
    using io :: read;
    using io :: putc;
    using io :: print;
    const int MAXN = 3e3+5,mod = 1e9+7;
    int n,m,k,u,v,a[MAXN],b[MAXN],s[MAXN*2],sz,f1[MAXN][MAXN],f2[MAXN],ans;
    char lt[MAXN<<1][MAXN<<1];
    it add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    int main(){
    	freopen("gu.in","r",stdin);
    	freopen("gu.out","w",stdout);
    	read(n),read(m),read(k);
    	for(ri i=1;i<=n;++i) read(a[i]),s[++sz]=a[i];
    	for(ri i=1;i<=m;++i) read(b[i]),s[++sz]=b[i];
    	sort(s+1,s+1+sz),sz=unique(s+1,s+1+sz)-s-1;
    	for(ri i=1;i<=n;++i) a[i]=lower_bound(s+1,s+1+sz,a[i])-s;
    	for(ri i=1;i<=n;++i) b[i]=lower_bound(s+1,s+1+sz,b[i])-s;
    	for(ri i=1;i<=k;++i){
    		read(u),read(v);
    		ri x=lower_bound(s+1,s+1+sz,u)-s;
    		ri y=lower_bound(s+1,s+1+sz,v)-s;
    		if(s[x]==u&&s[y]==v) lt[x][y]=1;
    	}
    	for(ri i=1;i<=n;++i){
    		ri sum=0;
    		for(ri j=1;j<=m;++j){
    			if(a[i]==b[j]) f1[i][j]=add(sum,1),ans=add(ans,f1[i][j]);
    			if(lt[b[j]][a[i]]) sum=add(sum,f2[j]);
    			f2[j]=add(f2[j],f1[i][j]);
    		}
    	}
    	print(ans);
    	return 0;
    }
    
  • 相关阅读:
    hdu5441Travel【并查集】
    笔试题 brotherword【tire || hash】
    20150917
    字典树模板
    三维凸包模板
    HUST1341A Simple Task【模拟】
    hust1350Trie【字典树+dfs || 字典树 + LCA】
    kmp笔试题。。
    poj3461Oulipo【kmp】
    【转帖】如何看外文文献
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11634493.html
Copyright © 2011-2022 走看看