acdream 1738 世风日下的哗啦啦族I 分块
世风日下的哗啦啦族I
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://acdream.info/problem?pid=1738
Description
"世风日下啊,女生不穿裙子的太少了"
"这不是社会的进步吗(逃"
"哎,是否可以建立一种结构统计一下各学院各专业各班级女生穿裙子的数量以及裙子的长度"
"然后查询区间裙子最短值?"
"并输出这个区间 穿这个裙子长度的妹子 有多少个?"
"然后判断下在有风的情况下,多少妹子是安全的."
"maya 哗啦啦族真是太可怕啦!"
Input
第一行 n,m表示n个妹子,m个操作
第二行 a1 a2 a3 …… an,n个整数,表示妹子一开始的裙子长度,如果穿的是裤子,ai=-1
下面m行:
总共3种操作
1 a b
修改a妹子的裙子,变成b长度
2 l r
查询[l,r]区间的妹子最短的裙子长度,并输出有多少个妹子穿这个长度裙子的
3 l r t
输出[l,r]区间的妹子身穿裙子长度小于等于t的个数
1<=n,m<=50000
1<=a<=n
1<=b<=50000
1<=ai<=50000
1<=l<=r<=n
0<=t<=50000
Output
根据询问,输出答案
具体看样例
Sample Input
3 3
1 2 3
1 1 4
2 1 3
3 1 3 2
Sample Output
2 1
1
HINT
题意
题解:
分块分块,暴力暴力!
暴力治天下!
(我迷之的二分分块会T……
http://pan.baidu.com/s/1hqu4qBa
代码:
#include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define test freopen("test.txt","r",stdin) #define maxn 2000001 #define mod 10007 #define eps 1e-9 const int inf=0x3f3f3f3f; const ll infll = 0x3f3f3f3f3f3f3f3fLL; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************** ll n,q,m,block; ll a[1000001],b[1000001],pos[1000001],add[1000001]; int minn[1000001]; int num[1000001]; ll find(ll x,ll v) { if(minn[x]>v) return 0; ll l=(x-1)*block+1,r=min(x*block,n); int num=0; for(int i=l;i<=r;i++) if(b[i]<=v) num++; else break; return num; /* while(l<r) { ll mid=(l+r)>>1; if(b[mid]<v) l=mid+1; else if(b[mid]>v) r=mid-1; } return r-last+1; */ } void reset(ll x) { ll l=(x-1)*block+1,r=min(x*block,n); for(ll i=l;i<=r;i++) b[i]=a[i]; sort(b+l,b+r+1); minn[x]=b[l]; num[x]=0; for(int i=l;i<=r;i++) if(b[i]==minn[x]) num[x]++; else break; } void update(ll x,ll v) { a[x]=v; reset(pos[x]); } ll query(ll x,ll y) { ll ans=inf; if(pos[x]==pos[y]) { for(int i=x;i<=y;i++) ans=min(a[i],ans); } else { for(int i=x;i<=pos[x]*block;i++) ans=min(ans,a[i]); for(int i=(pos[y]-1)*block+1;i<=y;i++) ans=min(ans,a[i]); } for(int i=pos[x]+1;i<pos[y];i++) ans=min(ans,(ll)minn[i]); return ans; } int query1(int x,int y,int z) { int ans=0; if(pos[x]==pos[y]) { for(int i=x;i<=y;i++) { if(a[i]==z) ans++; } } else { for(int i=x;i<=pos[x]*block;i++) { if(a[i]==z) ans++; } for(int i=(pos[y]-1)*block+1;i<=y;i++) { if(a[i]==z) ans++; } } for(int i=pos[x]+1;i<pos[y];i++) { if(minn[i]==z) ans+=num[i]; } return ans; } int deal(int x,int y,int z) { int ans=0; if(pos[x]==pos[y]) { for(int i=x;i<=y;i++) if(a[i]<=z) ans++; } else { for(int i=x;i<=pos[x]*block;i++) if(a[i]<=z) ans++; for(int i=(pos[y]-1)*block+1;i<=y;i++) if(a[i]<=z) ans++; } for(int i=pos[x]+1;i<pos[y];i++) ans+=find(i,z); return ans; } int main() { //test; //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); n=read(),q=read(); block=int(sqrt(n)); for(int i=1;i<=n;i++) { a[i]=read(); pos[i]=(i-1)/block+1; b[i]=a[i]; } int x,y,v,ch; if(n%block)m=n/block+1; else m=n/block; for(int i=1;i<=m;i++)reset(i); for(int i=1;i<=q;i++) { ch=read(); if(ch==1) { x=read(),v=read(); update(x,v); } else if(ch==2) { int x=read(),y=read(); int tmp=query(x,y),tmp2=query1(x,y,tmp); printf("%d %d\n",tmp,tmp2); } else { int x=read(),y=read(),z=read(); printf("%d\n",deal(x,y,z)); } } return 0; }