G题:URAL 1987
这题比赛的时候没看懂题目,现在又研究了好久,把题意理解错了,然后看队友交的代码都不懂,大帝一提醒才知道又把题意看错了^_^.因为把以前的线段树模板给放弃了,采取了更加飘逸的数组写法,所以还不是很熟悉……而且代码是看了别人的,代码与上次保存的代码都差不多,就是处理lazy标记的不一样而已,就是这个不一样,苦死我了,现在那个Pushup函数还没看懂怎么意思……唉……过段时间回来看看应该才懂吧……
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define sc(a,b) scanf("%d%d",&a,&b) #define pri(a) printf("%d\n",a) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define MM 1000005 #define MN 200050 #define INF 1000000009 #define eps 1e-7 using namespace std; typedef long long ll; int lazy[MN*8],a[MN/2],b[MN/2],c[MN*8],q[MN/2]; void pushdown(int i) //处理lazy标记 { if(lazy[i]!=-1) { lazy[i<<1]=lazy[i<<1|1]=lazy[i]; lazy[i]=-1; //去除标记 } } void pushup(int i) { if(lazy[i<<1]==lazy[i<<1|1]) lazy[i]=lazy[i<<1]; //不过这句话没看懂 else lazy[i]=-1; } void update(int i,int l,int r,int L,int R,int val) { if(L<=l&&r<=R) {lazy[i]=val;return ;} pushdown(i); //处理lazy标记往下传 int mid=(l+r)>>1; if(L<=mid) update(lson,L,R,val); if(R>mid) update(rson,L,R,val); pushup(i); } int query(int i,int l,int r,int w) { if(l==r) return lazy[i]; pushdown(i); //处理lazy标记往下传 int res,mid=(l+r)>>1; if(w<=mid) res=query(lson,w); else res=query(rson,w); pushup(i); return res; } int main() { int n,m,i,cnt=0; mem(lazy,-1); sca(n); for(i=1;i<=n;i++) { sc(a[i],b[i]); c[cnt++]=a[i]; c[cnt++]=b[i]; } sca(m); for(i=1;i<=m;i++) sca(q[i]),c[cnt++]=q[i]; sort(c,c+cnt); cnt=unique(c,c+cnt)-c; //去重离散化 for(i=1;i<=n;i++) { int L=lower_bound(c,c+cnt,a[i])-c+1; int R=lower_bound(c,c+cnt,b[i])-c+1; update(1,1,cnt,L,R,i); } for(i=1;i<=m;i++) pri(query(1,1,cnt,lower_bound(c,c+cnt,q[i])-c+1)); return 0; }
I题:URAL 1989
这题用的字符串哈希方法,以前学了那么多哈希函数,竟然没想到还有字符串哈希这个计算方法,真是没学完啊,哈希的思想太强大了,其实范神他们暴搞的也是用的哈希思想,只不过计算方法不一样罢了,实质还是一样的。然后上网找了好多代码,理解了字符串哈希后,敲了好久都没过,然后照着别人的敲了也没过,靠……原来是敲错了……
参照博客网址:http://www.cnblogs.com/zhsl/p/3395880.html
现在还有点不理解的就是为什么计算sum的时候还要乘上哈希值,这点至今未弄懂……
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define sc(a,b) scanf("%d%d",&a,&b) #define pri(a) printf("%d\n",a) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define MM 1000005 #define MN 100050 #define INF 1000000009 #define eps 1e-7 using namespace std; typedef long long ll; typedef unsigned long long ULL; ULL p[MN],s[MN][2]; //unsigned long long 能自动取模还是第一次知道 char str[MN]; int len; void update(int x,int flag,ULL val) { for(int i=x; i<=len; i+=i&(-i)) s[i][flag]+=val; } ULL sum(int x,int flag) { ULL ans=0; for(int i=x; i; i-=i&(-i)) ans+=s[i][flag]; return ans; } int main() { int n,i,a,b; char c,ss[30]; p[0]=1; for(i=1; i<MN; i++) p[i]=p[i-1]*27; scanf("%s",str); mem(s,0); len=strlen(str); for(i=0; i<len; i++) update(i+1,0,p[i]*(str[i]-'a'+1)), update(i+1,1,p[i]*(str[len-i-1]-'a'+1)); //字符串反转的哈希值 sca(n); while(n--) { scanf("%s",ss); if(!strcmp(ss,"change")) { scanf("%d %c",&a,&c); update(a,0,p[a-1]*(c-str[a-1])); //c-str[a-1]是因为刚开始加了str[a-1]所以这里减去才是更新 update(len-a+1,1,p[len-a]*(c-str[a-1])); str[a-1]=c; //刚开始少了这句话影响后面的更新一直WA靠……这人写得太飘逸了 } else { scanf("%d%d",&a,&b); ULL sum1=(sum(b,0)-sum(a-1,0))*p[len-b]; //为何还要乘以p[len-b]还不知道 ULL sum2=(sum(len-a+1,1)-sum(len-b,1))*p[a-1]; if(sum1==sum2) puts("Yes"); else puts("No"); } } return 0; }