@KirinBill
2017-09-23T23:37:59.000000Z
字数 6060
阅读 1570
题解 套题
NOIP出啥主席树...
目录

#include <cstdio>#include <algorithm>#include <climits>#include <cstring>using std::min;using std::max;const int MAXN=100005;const double EPS=1e-5;int n;int a[MAXN];long long k;double sum[MAXN];inline void pre_sum(double k){sum[0]=0;for(int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i]-k;}template<typename type>long long mge_sort(int l,int r,type a[]){static type tmp[MAXN];if(l==r) return 0;int mid=l+r>>1;long long ret=mge_sort(l,mid,a)+mge_sort(mid+1,r,a);int cur=l-1,lp=l,rp=mid+1;while(lp<=mid && rp<=r){if(a[lp]>a[rp]){tmp[++cur]=a[rp++];ret+=mid-lp+1;}else tmp[++cur]=a[lp++];}while(lp<=mid) tmp[++cur]=a[lp++];while(rp<=r) tmp[++cur]=a[rp++];memcpy(a+l,tmp+l,(r-l+1)*sizeof(type));return ret;}inline long long notp_cnt(){return mge_sort(0,n,sum);}inline double bin_chop(double l,double r){double mid;while(r-l>EPS){mid=(l+r)/2;pre_sum(mid);if(notp_cnt()>=k) r=mid;else l=mid;}return (l+r)/2;}int main(){freopen("ave.in","r",stdin);freopen("ave.out","w",stdout);scanf("%d%lld",&n,&k);int l=INT_MAX,r=INT_MIN;for(int i=1;i<=n;++i){scanf("%d",&a[i]);l=min(l,a[i]),r=max(r,a[i]);}printf("%.4lf",bin_chop(l,r));return 0;}

#include <cstdio>#include <algorithm>#include <cstring>using std::max;const int MAXN=105,P=998244353;int n,m,p,q;int f[MAXN][MAXN],C[MAXN][MAXN];struct matrix{int c[MAXN][MAXN];matrix(){memset(c,0,sizeof(c));}int* operator[] (int i){return c[i];}matrix& operator*= (matrix a){matrix b=*this;memset(c,0,sizeof(c));for(int i=1;i<=p;++i){for(int j=1;j<=p;++j){for(int k=1;k<=p;++k)c[i][j]=(c[i][j]+(long long)a[i][k]*b[k][j]%P)%P;}}return *this;}void be_unit(){for(int i=1;i<=p;++i)c[i][i]=1;}}ans,trans;inline int pow(int x,int y){int ret=1;for(;y;y>>=1,x=(long long)x*x%P){if(y&1) ret=(long long)ret*x%P;}return ret;}inline int inv(int x){return pow(x,P-2);}inline matrix pow(matrix x,int y){matrix ret;ret.be_unit();for(;y;y>>=1,x*=x){if(y&1) ret*=x;}return ret;}inline void pre_tab(){C[0][0]=1;for(int i=1;i<=p;++i){C[i][0]=C[i][i]=1;for(int j=1;j<i;++j)C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;}f[0][0]=1;for(int i=1;i<=n;++i){for(int j=1;j<=p;++j)f[i][j]=((long long)f[i-1][j-1]*(p-j+1)%P+(long long)f[i-1][j]*j%P)%P;}}inline void deal_mat(){for(int i=1;i<=p;++i){for(int j=1;j<=p;++j){for(int k=max(q,max(i,j));k<=p;++k)trans[i][j]=(trans[i][j]+(long long)C[i][i+j-k]*C[p-i][k-i]%P)%P;trans[i][j]=(long long)trans[i][j]*f[n][j]%P*inv(C[p][j])%P;}}ans=pow(trans,m-1);}int main(){freopen("color.in","r",stdin);freopen("color.out","w",stdout);scanf("%d%d%d%d",&n,&m,&p,&q);pre_tab();deal_mat();int sum=0;for(int i=1;i<=p;++i){for(int j=1;j<=p;++j)sum=(sum+(long long)f[n][i]*ans[i][j]%P)%P;}printf("%d",sum);return 0;}

tag,我们查询某个点上覆盖的区间数只用一直向下遍历,就能不重不漏了);
#include <cstdio>#include <algorithm>#include <cstring>using std::sort;const int MAXN=100005;int n,m,q;int a[MAXN];struct query{int l,r,x;friend bool operator< (const query &a,const query &b){return a.x<b.x;}}qry[MAXN];class CMT{private:int cnt;int rt[MAXN];struct node{int ls,rs,cnt;}d[MAXN*50];int cpy_nd(int u){d[++cnt]=d[u];return cnt;}void sgl_mdf(int pre,int &now,int l,int r,int val,int x){now=cpy_nd(pre);d[now].cnt+=x;if(l==r) return;int mid=l+r>>1;if(val<=mid) sgl_mdf(d[pre].ls,d[now].ls,l,mid,val,x);else sgl_mdf(d[pre].rs,d[now].rs,mid+1,r,val,x);}void rge_mdf(int pre,int &now,int l,int r,int lp,int rp,int x){now=cpy_nd(pre);if(lp<=l && r<=rp){d[now].cnt+=x;return;}int mid=l+r>>1;if(lp<=mid) rge_mdf(d[pre].ls,d[now].ls,l,mid,lp,rp,x);if(rp>mid) rge_mdf(d[pre].rs,d[now].rs,mid+1,r,lp,rp,x);}long long geq_cnt(int pre,int now,int l,int r,int val){if(val<=l) return d[now].cnt-d[pre].cnt;int mid=l+r>>1;long long ret=0;if(val<=mid) ret+=geq_cnt(d[pre].ls,d[now].ls,l,mid,val);if(val<=r) ret+=geq_cnt(d[pre].rs,d[now].rs,mid+1,r,val);return ret;}long long qry(int pre,int now,int l,int r,int val){if(l==r) return d[now].cnt-d[pre].cnt;int mid=l+r>>1;long long ret=d[now].cnt-d[pre].cnt;if(val<=mid) ret+=qry(d[pre].ls,d[now].ls,l,mid,val);else ret+=qry(d[pre].rs,d[now].rs,mid+1,r,val);return ret;}public:void clear(){cnt=0;memset(rt,0,sizeof(rt));memset(d,0,sizeof(d));}void ist(int pre,int now,int val){sgl_mdf(rt[pre],rt[now],1,n,val,1);}void ist(int pre,int now,int lp,int rp){rge_mdf(rt[pre],rt[now],1,n,lp,rp,1);}long long geq_cnt(int l,int r,int val){return geq_cnt(rt[l-1],rt[r],1,n,val);}long long qry(int l,int r,int val){return qry(rt[l-1],rt[r],1,n,val);}void cpy_his(int pre,int now){rt[now]=rt[pre];}}T;inline void deal_qry(){T.clear();sort(qry+1,qry+m+1);for(int i=1,j=1;i<=n;++i){T.cpy_his(i-1,i);while(qry[j].x==i && j<=m){T.ist(i,i,qry[j].l,qry[j].r);++j;}}}int main(){freopen("seq.in","r",stdin);freopen("seq.out","w",stdout);scanf("%d%d%d",&n,&m,&q);for(int i=1;i<=n;++i){scanf("%d",&a[i]);T.ist(i-1,i,a[i]);}long long ans=0;for(int i=1;i<=m;++i){scanf("%d%d%d",&qry[i].l,&qry[i].r,&qry[i].x);ans+=T.geq_cnt(qry[i].l,qry[i].r,qry[i].x);}printf("%lld\n",ans);deal_qry();long long p,v;for(int i=1;i<=q;++i){scanf("%lld%lld",&p,&v);p^=ans,v^=ans;if(a[p]<v) ans+=T.qry(a[p]+1,v,p);else if(a[p]>v) ans-=T.qry(v+1,a[p],p);a[p]=v;printf("%lld\n",ans);}return 0;}