B - Substring (atcoder.jp)
问题陈述
您将得到一个由小写英文字母组成的字符串 S 。 S 有多少不同的非空子字符串?
子字符串是一个连续子序列。例如,' xxx '是' yxxx '的子字符串,但不是' xxyxx '的子字符串。
解析:
对于数据范围不超过100,直接暴力枚举即可。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e6+10;
string s;
set <string> k;
void solve()
{cin>>s;for (int l=1;l<=s.size();l++){for (int i=0;i<s.size();i++){k.insert(s.substr(i,l));}}cout<<k.size();
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;// cin >> T;while (T--) solve();return 0;
}
C - Ideal Holidays (atcoder.jp)
问题陈述
在AtCoder王国,一个星期由 A+B 天组成,第一天到 A 天是假日,第 (A+1) 天到 (A+B) 天是工作日。
高桥有 N 个计划,第 i个计划安排在 Di 天后。
他忘了今天是星期几。确定是否有可能将他的所有计划都安排在假日。
解析:
首先暴力是不可取的,将所有的计划对(A+B)取模,就是每个计划执行时的相对的第几天,记录这些结果并去重,排序,假设序列长度为 k。这道题就可以转换成 在 1~k 的序列中,存在以一个数为起点,使得整个区间被长度 a 覆盖。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e5+10;
int n,a,b;
set <int> s;
vector <int> q;
void solve()
{cin>>n>>a>>b;for (int i=1;i<=n;i++) {int x;cin>>x;x--;s.insert(x%(a+b));}int m=a+b;for (auto x:s) q.push_back(x),q.push_back(x+m);sort (q.begin(),q.end());n=s.size();for (int i=0;i<n;i++){if (q[i+n-1]-q[i]<a){cout<<"Yes";return ;}}cout<<"No";
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;// cin >> T;while (T--) solve();return 0;
}
D - Popcount and XOR (atcoder.jp)
解析:
计算C在二进制中1的个数,合理地将这些 “1”,分配给 X 和 Y。不过要注意一些限制条件哦,气死我了,呜呜~~~
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e5+10;
int a,b,c;
int find(int x)
{int cnt=0;while (x){if (x&1) cnt++;x >>=1;}return cnt;
}
void solve()
{cin>>a>>b>>c;int cnt=find(c);int l;bool falg=0;for (int i=0;i<=60;i++){if (a-i+b-i==cnt&&a-i>=0&&b-i>=0){falg=1;l=i;break;}}if (!falg){cout<<-1;return ;}int a1=0,a2=0;int l1=a-l,l2=b-l;if (l+l1+l2>61||a-l<0||b-l<0) //此时 a1 和 a2 的范围超过了2^60{cout<<-1;return ;}for (int i=0;i<=60;i++){if (c&(1LL<<i)){if (l1>0) a1 +=(1LL<<i),l1--;else if (l2>0) a2 +=(1LL<<i),l2--; }else if (l>0) a1 +=(1LL<<i),a2 +=(1LL<<i),l--;}cout<<a1<<" "<<a2;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;// cin >> T;while (T--) solve();return 0;
}
E - Set Add Query (atcoder.jp)
解析:
考虑到暴力做法,对于每个操作,判断 x是否在集合 s 中,处理后加上集合 s 的大小,时间复杂度是 O(n^2)的,显然不可取。
通过观察可以发现,对于一个数 x ,它的贡献就是当它加入到集合 s 中,到当它离开集合 s 这段时间 s的大小的和。我们可以处理出,关于 s 的大小的前缀和,可以 O(1) 查询在这段时间内 x 的所贡献的 s的大小的和,当然我们要记录每个 x 的进入和离开的时间。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=2e5+10;
int n,m;
int a[N];
set <int> k;
int s[N];
int id[N];
void solve()
{cin>>n>>m;for (int i=1;i<=m;i++){int x;cin>>x;if (k.count(x)){a[x] +=s[i-1]-s[id[x]-1];k.erase(x);}else {k.insert(x);id[x]=i;}s[i]=s[i-1]+k.size();}for (auto x:k) a[x] +=s[m]-s[id[x]-1];for (int i=1;i<=n;i++) cout<<a[i]<<" ";
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;// cin >> T;while (T--) solve();return 0;
}