多校第一场
dls’s codes
sscanf的用法
相当于一个正则表达式,
1002 balanced sequence
题解
先预处理每一个串,然后贪心的去取就行了
感觉每一次都不能有巧妙的方法去预处理一些东西简化问题
题解
定义比较函数的时候遇到了坑。
注意不要添加多余的等号。
a == b return false, 不是return true;
然后注意减少比较的状态,否则会超时
ac code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; string raw[maxn]; int n; struct Node{ int l, r; }node[maxn]; bool cmp(Node a, Node b){ if(a.l>=a.r&&b.l<b.r) return true; if(a.l<a.r&&b.l>=b.r) return false; if(a.l>=a.r&&b.l>=b.r) return a.r<b.r; return a.l>b.l; } int main() { int t; ios::sync_with_stdio(false); cin>>t; while(t--){ cin>>n; int ans = 0; for(int i=0; i<n; i++) cin>>raw[i]; for(int i=0; i<n; i++){ stack<char> s; while(!s.empty()) s.pop(); for(int j=0; j<raw[i].length(); j++){ if(raw[i][j] == ')'){ if(!s.empty()&&s.top() == '('){ ans += 2; s.pop(); } else s.push(raw[i][j]); } else s.push('('); } int r, l; l = r = 0; while(!s.empty()){ char temp; temp = s.top(), s.pop(); if(temp == ')') r++; else l++; } node[i].l = l, node[i].r = r; } sort(node, node+n, cmp); int nl = 0; for(int i=0; i<n; i++){ if(nl<=node[i].r){ ans += 2*nl; nl = 0; nl += node[i].l; } else{ ans += 2*node[i].r; nl -= node[i].r; nl += node[i].l; } } cout<<ans<<endl; } return 0; }
|
1004
一类区间覆盖问题,quality说他做了10遍以上?看来经验还是不够啊qaq
题解
神仙怎么做的都有,,,类似于一类求mex的问题, mex可以用set, pq来维护
这个转移写的有点巧妙啊,一开始没有被覆盖的地方用长为1的区间来覆盖orz
ac code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <bits/stdc++.h> using namespace std; const int maxn = 1e6+10; int n, m; typedef pair<int, int> pii; typedef long long ll; int ans[maxn]; #define mp make_pair bool cmp(pii a, pii b){ if(a.first!=b.first) return a.first<b.first; else return a.second<b.second; } int main(){ ios::sync_with_stdio(false); //freopen("1004.in", "r", stdin); //freopen("10041.out", "w", stdout); int t; cin>>t; while(t--){ cin>>n>>m; vector<pii> a; int u, v; for(int i=0; i<m; i++){ cin>>u>>v; a.push_back(mp(u, v)); } for(int i=1; i<=n; i++) a.push_back(mp(i, i)); int l=1, r=1; priority_queue<int, vector<int>, greater<int> >pq; for(int i=1; i<=n; i++) pq.push(i); int sz = a.size(); sort(a.begin(), a.end(), cmp); for(int i=0; i<a.size(); i++){ while(l<a[i].first){ pq.push(ans[l++]); } while(r<=a[i].second) ans[r++]=pq.top(), pq.pop(); } for(int i=1; i<n; i++){ if(ans[i]) cout<<ans[i]<<" "; else cout<<1<<" "; } cout<< (ans[n]==0?1:ans[n]) <<endl; } return 0; } /* 4 8 3 1 3 3 6 4 8 */
|
1007
题解
(1, 3, 5, 7 …)·1
(2, 6, 10, 14 …)·2
(4, 12, 20, 28 …)·3
(8, 24, 40, 56 …)·4
…
题解
就是这样分块的去求就行了
我好想不擅长做这样的题目,智商不够啊emmm
ac code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<stdio.h> #include<iostream> using namespace std; #define mod 1000000007 typedef long long ll; ll a[105],f[105]; int main() { ll T; scanf("%lld",&T); a[0]=f[0]=1; for(ll i=1;i<=62;i++)a[i]=a[i-1]*2+1,f[i]=f[i-1]*2; ll inv=(mod+1)/2; while(T--) { ll pos=0,n,m,ma=-1,ans=0; scanf("%lld",&n); m=n; for(ll i=62;i>=0;i--) if(m-a[i]>=0) m-=a[i],pos=pos+(1ll<<i); pos+=(m>0); ll now=pos-1,num=0; for(ll i=1;f[i-1]<=now;i++) { ll s=f[i-1],step=(now-s)/f[i]+1,e=(step-1)*f[i]+s; ll haha=(s+e)%mod*(step%mod)%mod*inv%mod; ans=(ans+haha*i%mod)%mod; num+=step*i; } ans=(ans+1+(n-num-1)%mod*(pos%mod)%mod)%mod; printf("%lld\n",ans); } }
|
1011 time zone
转化成分钟来做比较的简单,我又直接来做,导致问题复杂化了
RMQ similar sequence
学习一种新的数据结构–笛卡尔树
它有如下的性质:
1.树中的元素满足二叉搜索树性质,要求按照中序遍历得到的序列为原数组序列(左儿子的key值小于自己,右儿子的key值大于自己)。
2.树中节点满足堆性质,节点的val值要大于其左右子节点的val值。
题解
题解链接
ac code
因为有除法,所以要求逆元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <iostream> #include <string> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <algorithm> using namespace std; typedef long long ll; const int MAX = 1e6+10; const ll mod = 1e9+7; int l[MAX], r[MAX], vis[MAX], stk[MAX], inv[MAX], siz[MAX]; int n; ll a[MAX]; int build() { int top = 0; for(int i=1;i<=n;i++) l[i] = r[i] = vis[i] = 0; for(int i=1;i<=n;i++){ int k = top; while(k > 0 && a[stk[k - 1]] < a[i]) --k; if(k) r[stk[k-1]] = i; if(k<top) l[i] = stk[k]; stk[k++] = i; top = k; } for(int i=1;i<=n;i++) vis[l[i]] = vis[r[i]] = 1; int ret = 0; for(int i=1;i<=n;i++) if(vis[i] == 0) ret = i; return ret; } void dfs(int root) { siz[root]=1; if(l[root]){ dfs(l[root]); siz[root]+=siz[l[root]]; } if(r[root]){ dfs(r[root]); siz[root]+=siz[r[root]]; } } int main() { int T; scanf("%d",&T); inv[1]=1; for(int i=2;i<MAX;i++) inv[i] = 1LL * inv[mod%i]*(mod-mod/i)%mod; while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); int root=build(); for(int i=0;i<=n;i++) siz[i]=0; dfs(root); ll ans=1; for(int i=1;i<=n;i++) ans=ans*inv[siz[i]]%mod; ans=(ans*n)%mod*inv[2]%mod; printf("%lld\n",ans); } return 0; }
|
未解决的问题