Codeforces Round #612 选讲
http://codeforces.com/contest/1287/problem/E2
一个串的价值只有它对每个字符的cnt。一种思路如下:比较1...n和1...n-1的所有子串的cnt,可以发现除了n个后缀之外,其它的子串两者都有,由此得到每个后缀的cnt。然而这超过了询问上限。我们可以用这种方法构造前半个串,然后用全串询问的对称性质(单独一次全串询问后理论上可以构造出一个可以对称旋转的串)来解决。具体的一种方法:$cnt_{i,x}$表示字符x在长度i的串中的出现次数。这个出现次数将随着x的位置而变化:在区间i...n-i+1,$cnt_{i,x}=i$,否则由x的位置单独决定。因此,$cnt_{i+1,x}-cnt_{i,x}$可以得到区间i+1...n-i内字符x的出现次数,由此得到字符x在每个对称位置的出现次数,本题解决。
http://codeforces.com/contest/1287/problem/F
一开始以为那个time是次数的意思。。。将所有碰撞事件按时间排序,第i个事件发生的概率为:前i-1个事件不发生的概率-前i个事件不发生的概率。这是一种限制相邻关系的待修改的全局查询问题。使用线段树维护被点分成的线段,维护某一区间内的子线段拼成的大线段中,最左端的点往左/往右以及最右端的点往左/往右的概率,合并时只有左区间右端点和右区间左端点相同时才能合并,修改只需把对应的子线段的对应概率置为0即可。为了避免端点的重复计算,一条线段可以不考虑左端点的概率。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n,leve,INV100,mod=998244353; 5 #define maxn 100011 6 #define maxeve maxn*3 7 struct Poi 8 { 9 int x,v,p; 10 }a[maxn]; 11 struct Eve 12 { 13 int id,a,b,timemod; double time; 14 bool operator < (const Eve &b) const {return time<b.time;} 15 }eve[maxeve]; 16 17 int powmod(int a,int b) 18 { 19 int ans=1; 20 while (b) 21 { 22 if (b&1) ans=1ll*ans*a%mod; 23 a=1ll*a*a%mod; 24 b>>=1; 25 } 26 return ans; 27 } 28 29 double calc(int i,int x,int y) 30 { 31 int v1,v2; 32 if (x) v1=a[i-1].v; else v1=-a[i-1].v; 33 if (y) v2=a[i].v; else v2=-a[i].v; 34 return 1.0*(a[i].x-a[i-1].x)/(v1-v2); 35 } 36 37 int calcmod(int i,int x,int y) 38 { 39 int v1,v2; 40 if (x) v1=a[i-1].v; else v1=-a[i-1].v; 41 if (y) v2=a[i].v; else v2=-a[i].v; 42 return ((0ll+a[i].x-a[i-1].x+mod)%mod)*1ll*powmod((0ll+v1-v2+mod+mod)%mod,mod-2)%mod; 43 } 44 45 struct smtnode{int ls,rs,v[2][2];}; 46 struct SMT 47 { 48 smtnode a[maxn<<1]; 49 int n,sz; 50 void clear(int N) {n=N; sz=0;} 51 void up(int x) 52 { 53 int p=a[x].ls,q=a[x].rs; 54 for (int i=0;i<2;i++) 55 for (int j=0;j<2;j++) 56 { 57 a[x].v[i][j]=0; 58 for (int k=0;k<2;k++) 59 a[x].v[i][j]=(a[x].v[i][j]+1ll*a[p].v[i][k]*a[q].v[k][j])%mod; 60 } 61 } 62 void build(int &x,int L,int R,Poi *b) 63 { 64 x=++sz; 65 if (L==R) 66 { 67 a[x].ls=a[x].rs=0; 68 a[x].v[0][1]=a[x].v[1][1]=b[L].p; 69 a[x].v[0][0]=a[x].v[1][0]=mod+1-b[L].p; 70 return; 71 } 72 int mid=(L+R)>>1; 73 build(a[x].ls,L,mid,b); 74 build(a[x].rs,mid+1,R,b); 75 up(x); 76 } 77 void build(Poi *b) {int x; build(x,1,n,b);} 78 int query() {return (0ll+a[1].v[0][0]+a[1].v[0][1])%mod;} 79 void Modify(int x,int L,int R,int p,int q,int r) 80 { 81 if (L==R) 82 { 83 a[x].v[q][r]=0; 84 return; 85 } 86 int mid=(L+R)>>1; 87 if (p<=mid) Modify(a[x].ls,L,mid,p,q,r); 88 else Modify(a[x].rs,mid+1,R,p,q,r); 89 up(x); 90 } 91 void modify(int p,int q,int r) {Modify(1,1,n,p,q,r);} 92 }t; 93 94 int main() 95 { 96 scanf("%d",&n); 97 INV100=powmod(100,mod-2); 98 for (int i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].v,&a[i].p),a[i].p=a[i].p*1ll*INV100%mod; 99 100 //0 zuo 1 you 101 102 leve=0; 103 for (int i=2;i<=n;i++) 104 { 105 eve[++leve]={i,1,0,calcmod(i,1,0),calc(i,1,0)}; 106 if (a[i-1].v>a[i].v) eve[++leve]={i,1,1,calcmod(i,1,1),calc(i,1,1)}; 107 if (a[i-1].v<a[i].v) eve[++leve]={i,0,0,calcmod(i,0,0),calc(i,0,0)}; 108 } 109 sort(eve+1,eve+1+leve); 110 111 t.clear(n); 112 t.build(a); 113 int ans=0; 114 for (int i=1,tmp,lastval=1;i<=leve;i++) 115 { 116 t.modify(eve[i].id,eve[i].a,eve[i].b); 117 tmp=t.query(); 118 ans=(ans+(lastval-tmp+mod)*1ll*(eve[i].timemod))%mod; 119 lastval=tmp; 120 } 121 printf("%d\n",ans); 122 return 0; 123 }