给定n个数字b_j,r个数字a_i 1.判断下面方程是否有整数解
1+∑i=1rxi∗ai=bj 2.r++,增加a_r,r最多为20 #include <cstdio> #include <queue> using namespace std; typedef long long ll; const int N=1e5+5,K=1e4+5; ll h; int n,m,k; ll a[N]; int c[N]; int len; ll d[K]; bool inq[K]; int head,tail,q[K]; typedef pair<int,int> pr; priority_queue<pr> s; int main(){ #ifdef DouBi freopen("in.cpp","r",stdin); #endif // Dou scanf("%I64d%d%d%d",&h,&n,&m,&k); d[0]=0; for(int u=1;u<k;u++) d[u]=h; for(int i=1;i<=n;i++){ scanf("%I64d%d",&a[i],&c[i]); if((--a[i])%k==0) s.push(pr(c[i],-i)); } while(m--){ int type; scanf("%d",&type); if(type==1){ ll w; scanf("%I64d",&w); head=tail=0; for(int u=0;u<k;u++) if(d[u]!=h) q[tail++]=u,inq[u]=1; while(head!=tail){ int u=q[head]; ++head==K?head=0:0; inq[u]=0; ll t=d[u]+w; int v=t%k; if(t<d[v]){ d[v]=t; if(!inq[v]) q[tail]=v,++tail==K?tail=0:0,inq[v]=1; } } while(!s.empty()) s.pop(); for(int i=1;i<=n;i++) if(a[i]>=d[a[i]%k]&&c[i]) s.push(pr(c[i],-i)); } else if(type==2){ int x,y; scanf("%d%d",&x,&y); c[x]-=y; if(a[x]>=d[a[x]%k]) s.push(pr(c[x],-x)); } else{ while(!s.empty()&&c[-s.top().second]!=s.top().first) s.pop(); if(s.empty()){ puts("0"); continue; } printf("%d\n",s.top().first); c[-s.top().second]=0; s.pop(); } } }