QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#48735 | #4391. Slayers Come | zzxzzx123 | WA | 111ms | 27664kb | C++17 | 3.4kb | 2022-09-15 13:53:42 | 2022-09-15 13:53:44 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
#define pii pair<ll,ll>
#define x first
#define y second
const int N=1e5+50;
ll a[N],b[N];
ll le[N],ri[N];
pii e[N];
int n,m;
struct node{
ll val,pos,id;
bool operator<(const node& a)const {
return val>a.val;
}
}li[N],rr[N];
ll g[N];
ll find(ll f[],ll x){
if(x==f[x]) return x;
return f[x]=find(f,f[x]);
}
void pre(){
//提前预处理出这个的况
for(int i=1;i<=n;i++){
g[i]=a[i+1]-b[i];//表示的是这个点
le[i]=i;
ri[i]=i;
}
//先处理出left
for(int i=1;i<=m;i++){
ll now=li[i].val,j=find(le,li[i].pos),id=li[i].id;
while((j-1)&&now<=g[j-1]){
int k=find(le,j-1);
le[j]=k;
j=k;
}
e[id].x=j;
}
for(int i=n;i;i--){
g[i]=a[i-1]-b[i];
}
for(int i=1;i<=m;i++){
ll now=rr[i].val,j=find(ri,rr[i].pos),id=rr[i].id;
while((j+1<=n)&&now<=g[j+1]){
int k=find(ri,j+1);
ri[j]=k;
j=k;
}
e[id].y=j;
}
}
struct tree{
ll l,r,len,flag;
ll sum,add,mul;//表示的是这个区间的dp值的和
}t[N<<2];
void sol(tree& a,ll mul,ll add){
a.sum=(a.sum*mul%mod+add*a.len%mod)%mod;
a.mul=a.mul*mul%mod;
a.add=(a.add*mul%mod+add)%mod;
}
void push_down(int p){
if(t[p].flag){
sol(t[p<<1],t[p].mul,t[p].add);
sol(t[p<<1|1],t[p].mul,t[p].add);
t[p].mul=1,t[p].add=0;
t[p].flag=0;
}
}//下放的标记
void push_up(int p){
t[p].sum=(t[p<<1].sum+t[p<<1|1].sum)%mod;//提供一个答案
}//只需要进行传递一个操作
void build(int p,int l,int r){
//其他的都是只能够不选择
t[p].flag=t[p].sum=0;
t[p].add=0;
t[p].mul=1;//区间乘
t[p].l=l,t[p].r=r;
t[p].len=r-l+1;
if(l==r){
return ;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
push_up(p);
}
ll query(int p,int x,int y){
if(t[p].l>=x&&t[p].r<=y){
return t[p].sum;
}
ll val=0;
int mid=t[p].l+t[p].r>>1;
push_down(p);
if(x<=mid){
val+=query(p<<1,x,y);
val%=mod;
}
if(y>mid)
{
val+=query(p<<1|1,x,y);
val%=mod;
}
return val;
}
void add(int p,int x,ll k)//单点的修改
{
if(t[p].l==t[p].r){
t[p].sum=(t[p].sum+k)%mod;
return;
}
int mid=t[p].l+t[p].r>>1;
push_down(p);
if(x<=mid){
add(p<<1,x,k);
}else add(p<<1|1,x,k);
push_up(p);
}
void update(int p,int x,int y,ll k=2)//区间乘,并且乘的都是2
{
if(t[p].l>=x&&t[p].r<=y){
t[p].flag=1;
//然后是开始进行相乘
t[p].mul=t[p].mul*2%mod;
t[p].add=t[p].add*2%mod;
t[p].sum=t[p].sum*2%mod;
//开始进行操作,打上懒标记
return;
}
push_down(p);
int mid=t[p].l+t[p].r>>1;
if(x<=mid){
update(p<<1,x,y);
}
if(y>mid){
update(p<<1|1,x,y);
}
push_up(p);//记得啊
}
int main(){
int tt;
scanf("%d",&tt);
while(tt--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
}
ll pos,x,y;
for(int i=1;i<=m;i++){
scanf("%lld%lld%lld",&pos,&x,&y);
li[i]={x,pos,i};
rr[i]={y,pos,i};
}
sort(li+1,li+m+1),sort(rr+1,rr+m+1);
pre();
sort(e+1,e+m+1);
build(1,0,n);
add(1,0,1);//初始化答案
for(int i=1;i<=m;i++){
int l=e[i].x,r=e[i].y;
//对于这个的话都是修改一个恰好的
//一个是直接加
update(1,r,n);//全部都乘上2
ll val1=query(1,l-1,r-1);
add(1,r,val1);//这个是单点修改
//区间乘
}
printf("%lld\n",query(1,n,n));
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 111ms
memory: 27664kb
input:
100 94361 94314 33869598 5185471 618720133 505036749 409602893 40833389 73363932 853969687 132417645 381351032 465347847 676007624 210787499 3355224 991034578 503557482 118882583 12886598 821718576 953581962 979222818 458179522 17341621 962353208 11732262 180321038 947467293 869555337 27442910 91111...
output:
210787328 910315295 0 14640782 476456026 214299257 758402671 355931964 67099192 8192 501124520 0 713040969 268315788 509937319 940220350 481742520 320085546 301995260 703668713 730928980 714057465 229552036 290125029 768 243305403 642750654 661172187 786466491 601981094 138399255 0 845809031 4666584...
result:
wrong answer 1st lines differ - expected: '790989612', found: '210787328'