2019牛客多校第4场
训练记录
D题做了太长时间,一直在找规律,其实lfw一开始就有接近正解的想法,不过还是想要找规律快速过掉,直到找规律找不到以后才开始从二进制每一位的奇偶开始考虑。
题目链接:https://ac.nowcoder.com/acm/contest/884#question
题解
A meeting
题解:https://blog.csdn.net/liufengwei1/article/details/97557656
1 #include<bits/stdc++.h> 2 #define maxl 100010 3 4 using namespace std; 5 const int inf=2e9; 6 7 int n,k,cnt,ans; 8 int ehead[maxl]; 9 int f[maxl],mxfa[maxl],mxs[maxl],secmxs[maxl]; 10 bool mxflag[maxl],secmxflag[maxl],faflag[maxl]; 11 struct ed 12 { 13 int to,nxt,mi; 14 }e[maxl<<1]; 15 bool in[maxl]; 16 17 inline void add(int u,int v) 18 { 19 e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt; 20 } 21 22 inline void prework() 23 { 24 for(int i=1;i<=n;i++) 25 ehead[i]=0,f[i]=0,in[i]=false; 26 int u,v; 27 cnt=0; 28 for(int i=1;i<=n-1;i++) 29 { 30 scanf("%d%d",&u,&v); 31 add(u,v);add(v,u); 32 } 33 for(int i=1;i<=k;i++) 34 { 35 scanf("%d",&u); 36 in[u]=true; 37 } 38 } 39 40 inline void gets(int u,int fa) 41 { 42 int v,tmp; 43 if(in[u]) 44 mxflag[u]=true; 45 for(int i=ehead[u];i;i=e[i].nxt) 46 { 47 v=e[i].to; 48 if(v==fa) continue; 49 gets(v,u); 50 if(in[v]) 51 { 52 in[u]=true; 53 if(mxflag[v]) 54 { 55 tmp=mxs[v]+1; 56 if(tmp>mxs[u]) 57 { 58 secmxs[u]=mxs[u],mxs[u]=tmp; 59 secmxflag[u]=mxflag[u]; 60 mxflag[u]=true; 61 } 62 else if(tmp>secmxs[u]) 63 secmxs[u]=tmp,secmxflag[u]=true; 64 } 65 } 66 } 67 } 68 69 inline void getf(int u,int fa) 70 { 71 int v,tmp; 72 if(u==1) f[1]=mxs[1]; 73 else 74 { 75 if(mxs[u]+1==mxs[fa]) 76 { 77 if(secmxflag[fa]) 78 { 79 mxfa[u]=max(mxfa[u],secmxs[fa]+1); 80 faflag[u]=true; 81 } 82 } 83 else 84 { 85 if(mxflag[fa]) 86 { 87 mxfa[u]=max(mxfa[u],mxs[fa]+1); 88 faflag[u]=true; 89 } 90 } 91 if(faflag[fa]) 92 { 93 mxfa[u]=max(mxfa[u],mxfa[fa]+1); 94 faflag[u]=true; 95 } 96 } 97 for(int i=ehead[u];i;i=e[i].nxt) 98 { 99 v=e[i].to; 100 if(v==fa) continue; 101 getf(v,u); 102 } 103 if(faflag[u]) 104 f[u]=mxfa[u]; 105 if(mxs[u]) 106 f[u]=max(f[u],mxs[u]); 107 } 108 109 inline void mainwork() 110 { 111 for(int i=1;i<=n;i++){ 112 f[i]=0,mxs[i]=0,secmxs[i]=0,mxfa[i]=0; 113 mxflag[i]=secmxflag[i]=faflag[i]=false; 114 } 115 gets(1,0); 116 mxfa[1]=0; 117 getf(1,0); 118 ans=inf; 119 for(int i=1;i<=n;i++) 120 ans=min(ans,f[i]); 121 } 122 123 inline void print() 124 { 125 printf("%lld\n",ans); 126 } 127 128 int main() 129 { 130 while(~scanf("%d%d",&n,&k)) 131 { 132 prework(); 133 mainwork(); 134 print(); 135 } 136 return 0; 137 }
B xor
题解:https://blog.csdn.net/liufengwei1/article/details/97620377
1 #include<bits/stdc++.h> 2 #define maxl 50010 3 using namespace std; 4 5 int n,m,q; 6 int sz[maxl]; 7 unsigned int a[maxl][33]; 8 struct LB 9 { 10 int cnt;bool flag; 11 unsigned int p[32],f[32]; 12 inline void init() 13 { 14 cnt=0;flag=false; 15 memset(f,0,sizeof(f)); 16 memset(p,0,sizeof(p)); 17 } 18 inline bool insert(unsigned int x) 19 { 20 for(int i=31;i>=0;i--) 21 if(x&(1ll<<i)) 22 { 23 if(!p[i]) 24 { 25 p[i]=x; 26 break; 27 } 28 x^=p[i]; 29 } 30 return x>0; 31 } 32 inline void insert2(unsigned int x) 33 { 34 unsigned int tmp=x; 35 for(int i=31;i>=0;i--) 36 if(x>>i) 37 { 38 if(!p[i]) 39 { 40 f[i]=tmp;p[i]=x; 41 return; 42 } 43 x^=p[i];tmp^=f[i]; 44 } 45 } 46 inline bool find(unsigned int x) 47 { 48 for(int i=31;i>=0;i--) 49 if(x>>i) 50 { 51 if(!p[i]) return 0; 52 x^=p[i]; 53 } 54 return x==0; 55 } 56 unsigned int calc(unsigned int x) 57 { 58 unsigned int ret=0; 59 for(int i=31;i>=0;i--) 60 if(x>>i) 61 { 62 ret^=f[i]; 63 x^=p[i]; 64 } 65 return ret; 66 } 67 }; 68 struct node 69 { 70 int l,r; 71 LB xxj; 72 }tree[maxl*4]; 73 74 inline void pushup(int k) 75 { 76 LB tmp=tree[k<<1].xxj; 77 LB ans; 78 ans.init(); 79 for(int i=31;i>=0;i--) 80 { 81 unsigned int x=tree[k<<1|1].xxj.p[i]; 82 if(tmp.find(x)) 83 ans.insert(x^tmp.calc(x)); 84 else 85 tmp.insert2(x); 86 } 87 tree[k].xxj=ans; 88 } 89 90 inline void build(int k,int l,int r) 91 { 92 tree[k].l=l;tree[k].r=r;tree[k].xxj.init(); 93 if(l==r) 94 { 95 for(int i=1;i<=sz[l];i++) 96 tree[k].xxj.insert(a[l][i]); 97 return; 98 } 99 int mid=(l+r)>>1; 100 build(k<<1,l,mid); 101 build(k<<1|1,mid+1,r); 102 pushup(k); 103 } 104 105 inline void prework() 106 { 107 for(int i=1;i<=n;i++) 108 { 109 scanf("%d",&sz[i]); 110 for(int j=1;j<=sz[i];j++) 111 scanf("%u",&a[i][j]); 112 } 113 build(1,1,n); 114 } 115 116 inline bool query(int k,int l,int r,unsigned int x) 117 { 118 if(tree[k].l==l && tree[k].r==r) 119 return tree[k].xxj.find(x); 120 int mid=(tree[k].l+tree[k].r)>>1; 121 if(r<=mid) 122 return query(k<<1,l,r,x); 123 else if(l>mid) 124 return query(k<<1|1,l,r,x); 125 else 126 return query(k<<1,l,mid,x) && query(k<<1|1,mid+1,r,x); 127 } 128 129 inline void mainwork() 130 { 131 int l,r;unsigned int x; 132 for(int i=1;i<=q;i++) 133 { 134 scanf("%d%d%u",&l,&r,&x); 135 if(query(1,l,r,x)) 136 puts("YES"); 137 else 138 puts("NO"); 139 } 140 } 141 142 int main() 143 { 144 while(~scanf("%d%d",&n,&q)) 145 { 146 prework(); 147 mainwork(); 148 // print(); 149 } 150 return 0; 151 }
C sequence
单调栈维护每个数字的最小值统治的区域,线段树找区间最值
1 #include <bits/stdc++.h> 2 #define my_max(a, b) ((a) > (b) ? (a) : (b)) 3 #define my_min(a, b) ((a) < (b) ? (a) : (b)) 4 #define fi first 5 #define se second 6 #define pb push_back 7 #define eb emplace_back 8 #define rep(i, s, t) for(int i = (int)(s); i <= (int)(t); i++) 9 #define rev(i, t, s) for(int i = (int)(t); i >= (int)(s); i--) 10 #define lson rt << 1 11 #define rson rt << 1 | 1 12 #define sz(x) (int)(x).size() 13 14 typedef long long ll; 15 typedef long double lb; 16 typedef std::pair<int, int> pii; 17 typedef std::pair<ll, ll> pll; 18 typedef std::vector<int> VI; 19 typedef std::vector<ll> VL; 20 #include <ext/pb_ds/tree_policy.hpp> 21 #include <ext/pb_ds/assoc_container.hpp> 22 using namespace __gnu_pbds; 23 using namespace std; 24 typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> rbtree; 25 ll gcd(ll x, ll y){ return y % x == 0 ? x : gcd(y % x, x); } 26 template<class T>T my_abs(T a){ if(a < 0) a = -a; return a; } 27 inline ll read() 28 { 29 ll ret = 0, sign = 1; 30 char c = getchar(); 31 while(c < '0' || c > '9'){ if(c == '-') sign = -1; c = getchar();} 32 while(c >= '0' && c <= '9'){ ret = ret * 10 + c - '0'; c = getchar(); } 33 return ret * sign; 34 } 35 inline void write(ll x) 36 { 37 if(x < 0){ 38 putchar('-'); 39 x = -x; 40 } 41 if(x > 9) write(x / 10); 42 putchar(x % 10 + '0'); 43 } 44 45 const int maxn = 5e6 + 7; 46 const ll inf = 1e18; 47 int n; 48 struct SegmentTree{ 49 ll Max[maxn << 2], Min[maxn << 2]; 50 void init(ll *a){ 51 build(1, 1, n, a); 52 } 53 void push_up(int rt) 54 { 55 Min[rt] = min(Min[lson], Min[rson]); 56 Max[rt] = max(Max[lson], Max[rson]); 57 } 58 void build(int rt, int l, int r, ll *a) 59 { 60 if(l == r){ 61 Max[rt] = Min[rt] = a[l]; 62 return ; 63 } 64 int mid = (l + r) >> 1; 65 build(lson, l, mid, a); 66 build(rson, mid + 1, r, a); 67 push_up(rt); 68 } 69 ll queryMin(int ql, int qr, int rt = 1, int l = 1, int r = n){ 70 if(ql == l && qr == r) return Min[rt]; 71 int mid = (l + r) >> 1; 72 ll res = inf; 73 if(qr <= mid) res = queryMin(ql, qr, lson, l, mid); 74 else if(ql > mid) res = queryMin(ql, qr, rson, mid + 1, r); 75 else{ 76 res = min(queryMin(ql, mid, lson, l, mid), queryMin(mid + 1, qr, rson, mid + 1, r)); 77 } 78 return res; 79 } 80 ll queryMax(int ql, int qr, int rt = 1, int l = 1, int r = n) 81 { 82 if(ql == l && qr == r) return Max[rt]; 83 int mid = (l + r) >> 1; 84 ll res = -inf; 85 if(qr <= mid) res = queryMax(ql, qr, lson, l, mid); 86 else if(ql > mid) res = queryMax(ql, qr, rson, mid + 1, r); 87 else{ 88 res = max(queryMax(ql, mid, lson, l, mid), queryMax(mid + 1, qr, rson, mid + 1, r)); 89 } 90 return res; 91 } 92 }pre; 93 ll presum[maxn], a[maxn],b[maxn]; 94 int L[maxn], R[maxn], st[maxn], top; 95 int main() 96 { 97 98 scanf("%d", &n); 99 presum[1] = 0; 100 101 for(int i = 2; i <= n + 1; i++) 102 scanf("%lld", a + i); 103 for(int i = 2; i <= n + 1; i++) 104 { 105 scanf("%lld", b + i); 106 presum[i] = presum[i - 1] + b[i]; 107 } 108 top = 0; 109 for(int i = 2; i <= n + 1; i++) 110 { 111 while(top > 0 && a[st[top]] >= a[i]) top--; 112 if(top > 0) L[i] = st[top] + 1; 113 else L[i] = 1; 114 st[++top] = i; 115 } 116 top = 0; 117 for(int i = n + 1; i >= 2; i--) 118 { 119 while(top > 0 && a[st[top]] >= a[i]) top--; 120 if(top > 0) R[i] = st[top] - 1; 121 else R[i] = n + 1; 122 st[++top] = i; 123 } 124 n++; 125 pre.init(presum); 126 ll ans = -inf; 127 128 for(int i = 2; i <= n; i++) 129 { 130 int l = L[i], r = R[i]; 131 l = max(l - 1, 1); 132 133 ll Maxl = pre.queryMax(l, i), Minl = pre.queryMin(l, i); 134 ll Maxr = pre.queryMax(i, r), Minr = pre.queryMin(i, r); 135 ll ans1 = (Maxr - Minl) * a[i]; 136 ll ans2 = (Minr - Maxl) * a[i]; 137 138 ans1 = max(ans1, ans2); ans1 = max(ans1, a[i] * a[i]); 139 ans = max(ans, ans1); 140 } 141 printf("%lld\n", ans); 142 return 0; 143 144 }
D triples I
题解:https://blog.csdn.net/liufengwei1/article/details/97551038
1 #include<bits/stdc++.h> 2 #define maxl 65 3 using namespace std; 4 5 long long top,anscnt; 6 long long a; 7 long long anum[maxl]; 8 long long ans[3],mi[maxl]; 9 bool in[maxl]; 10 11 inline void prework() 12 { 13 scanf("%lld",&a); 14 long long x=a; 15 top=0;long long cnt=0; 16 while(x>0) 17 { 18 cnt++; 19 if(x%2ll==1ll) 20 anum[++top]=cnt; 21 x/=2ll; 22 } 23 } 24 25 inline void mainwork() 26 { 27 long long x; 28 if(a%3ll==0ll) 29 { 30 anscnt=1; 31 ans[1]=a; 32 return; 33 } 34 long long cnt1=0,cnt2=0,sum=0,num1,num2; 35 for(long long i=1;i<=top;i++) 36 { 37 if(anum[i]%2ll==1ll) 38 cnt1++; 39 else 40 cnt2++; 41 } 42 sum=cnt1+2*cnt2; 43 if(sum%3ll==1ll) 44 { 45 if(cnt1>=1ll) 46 { 47 num1=cnt1-1; 48 num2=cnt2; 49 } 50 else 51 { 52 num1=cnt1; 53 num2=cnt2-2; 54 } 55 } 56 else 57 { 58 if(cnt2>=1ll) 59 { 60 num1=cnt1; 61 num2=cnt2-1; 62 } 63 else 64 { 65 num1=cnt1-2; 66 num2=cnt2; 67 } 68 } 69 long long rescnt1=cnt1-num1,rescnt2=cnt2-num2; 70 anscnt=2; 71 ans[1]=0;ans[2]=0; 72 cnt1=0;cnt2=0; 73 for(long long i=1;i<=top;i++) 74 in[i]=false; 75 for(long long i=1;i<=top;i++) 76 { 77 if(anum[i]%2ll==1ll) 78 { 79 if(cnt1<num1) 80 cnt1++,ans[1]|=mi[anum[i]],in[i]=true; 81 else 82 ans[2]|=mi[anum[i]]; 83 } 84 else 85 { 86 if(cnt2<num2) 87 cnt2++,ans[1]|=mi[anum[i]],in[i]=true; 88 else 89 ans[2]|=mi[anum[i]]; 90 } 91 } 92 if((rescnt1+2*rescnt2)%3ll==1) 93 { 94 if(cnt2>0) 95 { 96 for(long long i=1;i<=top;i++) 97 if(in[i] && anum[i]%2==0) 98 { 99 ans[2]|=mi[anum[i]]; 100 break; 101 } 102 } 103 else 104 { 105 bool flag=false; 106 for(long long i=1;i<=top;i++) 107 if(in[i] && anum[i]%2==1) 108 { 109 ans[2]|=mi[anum[i]]; 110 if(flag) break; 111 flag=true; 112 } 113 } 114 } 115 else 116 { 117 if(cnt1>0) 118 { 119 for(long long i=1;i<=top;i++) 120 if(in[i] && anum[i]%2==1) 121 { 122 ans[2]|=mi[anum[i]]; 123 break; 124 } 125 } 126 else 127 { 128 bool flag=false; 129 for(long long i=1;i<=top;i++) 130 if(in[i] && anum[i]%2==0) 131 { 132 ans[2]|=mi[anum[i]]; 133 if(flag) break; 134 flag=true; 135 } 136 } 137 } 138 } 139 140 inline void print() 141 { 142 printf("%lld ",anscnt); 143 for(long long i=1;i<=anscnt;i++) 144 printf("%lld%c",ans[i],(i==anscnt)?'\n':' '); 145 } 146 147 int main() 148 { 149 mi[1]=1; 150 for(long long i=2;i<=63;i++) 151 mi[i]=mi[i-1]*2ll; 152 long long t; 153 scanf("%lld",&t); 154 for(long long i=1;i<=t;i++) 155 { 156 prework(); 157 mainwork(); 158 print(); 159 } 160 return 0; 161 }
E triples II
unsolved
F merge
unsolved
G tree
unsolved
H RNGs
unsolved
I string
题解:https://www.cnblogs.com/songorz/p/11257819.html
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define pii pair<int,int> 5 #define pil pair<int,long long> 6 const int INF=0x3f3f3f3f; 7 const ll inf=0x3f3f3f3f3f3f3f3fll; 8 inline int read() 9 { 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 const int maxn=4e5+10; 16 const int MAXN=4e5+10; 17 char str[maxn]; 18 int s[maxn]; 19 ll ans; 20 struct SAM{ 21 int l[maxn<<1],fa[maxn<<1],nxt[maxn<<1][30]; 22 int last,cnt; 23 24 void Init() 25 { 26 ans=0;last=cnt=1; 27 l[cnt]=fa[cnt]=0; 28 memset(nxt[cnt],0,sizeof(nxt[cnt])); 29 } 30 31 int NewNode() 32 { 33 ++cnt; 34 memset(nxt[cnt],0,sizeof(nxt[cnt])); 35 l[cnt]=fa[cnt]=0; 36 return cnt; 37 } 38 39 void Insert(int ch) 40 { 41 int np=NewNode(),p=last; 42 last=np; l[np]=l[p]+1; 43 while(p&&!nxt[p][ch]) nxt[p][ch]=np,p=fa[p]; 44 if(!p) fa[np]=1; 45 else 46 { 47 int q=nxt[p][ch]; 48 if(l[p]+1==l[q]) fa[np]=q; 49 else 50 { 51 int nq=NewNode(); 52 memcpy(nxt[nq],nxt[q],sizeof(nxt[q])); 53 fa[nq]=fa[q]; 54 l[nq]=l[p]+1; 55 fa[np]=fa[q]=nq; 56 while(nxt[p][ch]==q) nxt[p][ch]=nq,p=fa[p]; 57 } 58 } 59 ans+=1ll*(l[last]-l[fa[last]]); 60 } 61 62 }sam; 63 64 struct Palindromic_Tree{ 65 int next[MAXN][26]; 66 int fail[MAXN]; 67 int cnt[MAXN]; 68 int num[MAXN]; 69 int len[MAXN]; 70 int S[MAXN]; 71 int last; 72 int n; 73 int p; 74 75 int newnode(int l) 76 { 77 for(int i=0;i<26;++i) next[p][i]=0; 78 cnt[p]=0; 79 num[p]=0; 80 len[p]=l; 81 return p++; 82 } 83 84 void Init() 85 { 86 p=0; 87 newnode( 0); 88 newnode(-1); 89 last=0; 90 n=0; 91 S[n]=-1; 92 fail[0]=1; 93 } 94 95 int get_fail(int x) 96 { 97 while(S[n-len[x]-1]!=S[n])x=fail[x] ; 98 return x ; 99 } 100 101 void add(int c) 102 { 103 S[++ n]=c; 104 int cur=get_fail(last) ; 105 if(!next[cur][c]) 106 { 107 int now=newnode(len[cur]+2) ; 108 fail[now]=next[get_fail(fail[cur])][c] ; 109 next[cur][c]=now ; 110 num[now]=num[fail[now]]+1; 111 } 112 last=next[cur][c]; 113 cnt[last]++; 114 } 115 116 ll count() 117 { 118 ll res=p*1ll; 119 for(int i=p-1;i>=0;--i) cnt[fail[i]]+=cnt[i]; 120 //for(int i=1;i<=p;++i) res+=cnt[i]; 121 //cout<<"res "<<res<<endl; 122 return (res-2); 123 } 124 } pam; 125 126 int main() 127 { 128 scanf("%s",str); 129 int len=strlen(str); 130 131 sam.Init(); 132 for(int i=0;i<len;++i) sam.Insert(str[i]-'a'); 133 sam.Insert(28); 134 for(int i=len-1;i>=0;--i) sam.Insert(str[i]-'a'); 135 ans-=1ll*(len+1)*(len+1); 136 //cout<<"ans "<<ans<<endl; 137 pam.Init(); 138 for(int i=0;i<len;++i) pam.add(str[i]-'a'); 139 ans=ans+pam.count(); 140 141 printf("%lld\n",(ans/2ll)); 142 143 144 return 0; 145 }
J free
k维最短路
1 #include<bits/stdc++.h> 2 #define maxl 1010 3 using namespace std; 4 5 const int inf=2e9; 6 7 int n,m,S,T,K,cnt; 8 int ehead[maxl]; 9 int dis[maxl][maxl]; 10 struct ed 11 { 12 int to,nxt,l; 13 }e[maxl*2]; 14 struct node 15 { 16 int val,k,u; 17 bool operator > (const node &b)const 18 { 19 if(val==b.val) 20 { 21 if(k==b.k) 22 return u>b.u; 23 else 24 return k>b.k; 25 } 26 else return val>b.val; 27 } 28 }; 29 priority_queue<node,vector<node>,greater<node>> q; 30 31 inline void add(int u,int v,int l) 32 { 33 e[++cnt].to=v;e[cnt].l=l; 34 e[cnt].nxt=ehead[u];ehead[u]=cnt; 35 } 36 37 inline void prework() 38 { 39 for(int i=1;i<=n;i++) 40 ehead[i]=0; 41 scanf("%d%d%d",&S,&T,&K); 42 cnt=0;int u,v,l; 43 for(int i=1;i<=m;i++) 44 { 45 scanf("%d%d%d",&u,&v,&l); 46 if(u!=v) 47 add(u,v,l),add(v,u,l); 48 } 49 } 50 51 inline void mainwork() 52 { 53 for(int i=1;i<=n;i++) 54 for(int k=0;k<=K;k++) 55 dis[i][k]=inf; 56 node d;int u,v; 57 dis[S][0]=0; 58 q.push(node{0,0,S}); 59 while(!q.empty()) 60 { 61 do 62 { 63 d=q.top();q.pop(); 64 u=d.u; 65 } 66 while(d.val>dis[u][d.k] && !q.empty()); 67 for(int i=ehead[u];i;i=e[i].nxt) 68 { 69 v=e[i].to; 70 if(d.k<K) 71 { 72 if(d.val<dis[v][d.k+1]) 73 { 74 dis[v][d.k+1]=d.val; 75 q.push(node{d.val,d.k+1,v}); 76 } 77 } 78 if(d.val+e[i].l<dis[v][d.k]) 79 { 80 dis[v][d.k]=d.val+e[i].l; 81 q.push(node{dis[v][d.k],d.k,v}); 82 } 83 } 84 } 85 } 86 87 inline void print() 88 { 89 int ans=inf; 90 for(int k=0;k<=K;k++) 91 ans=min(dis[T][k],ans); 92 printf("%d\n",ans); 93 } 94 95 int main() 96 { 97 while(~scanf("%d%d",&n,&m)) 98 { 99 prework(); 100 mainwork(); 101 print(); 102 } 103 return 0; 104 }
K number
DP计数
1 #include<bits/stdc++.h> 2 #define maxl 100010 3 using namespace std; 4 5 int n; 6 int sum[4]; 7 char s[maxl]; 8 long long ans; 9 10 inline void prework() 11 { 12 n=strlen(s+1); 13 for(int i=0;i<=3;i++) 14 sum[i]=0; 15 } 16 17 inline void mainwork() 18 { 19 ans=0; 20 int cnt1=0,cnt2=0,tmp=0; 21 sum[0]=1; 22 for(int i=1;i<=n;i++) 23 { 24 tmp=(tmp+s[i]-'0')%3; 25 if(s[i]=='0' && s[i-1]=='0') 26 ans+=sum[tmp]; 27 else if(s[i]=='0') 28 ans+=1; 29 sum[tmp]+=1; 30 } 31 } 32 33 inline void print() 34 { 35 printf("%lld\n",ans); 36 } 37 38 int main() 39 { 40 while(~scanf("%s",s+1)) 41 { 42 prework(); 43 mainwork(); 44 print(); 45 } 46 return 0; 47 }