C. Eugene and an array
题目大意就是说给你以1个数组,数组内连续的子序列的子序列中如果没有一个和为0则这就是好序列,求所有的好序列数量
解题思路:总的子串数量为(n + 1) n / 2*
我们就要求出和包含和为0子串的子串的数量
举个例子对于1 2 -2 1中间有一段前缀和和为0那么总的子串为2*2=4,是1 2 -2,2 -2,2 -2 1,1 2 -2 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define f first
#define s second
using namespace std;
const int N = 2e5 + 10, eps = 1e-10;
typedef long long ll;
typedef unsigned long long ULL;
int a[N], b[N];
int num[N], fnum[N];
map<ll, ll> MP;
int main()
{
IOS;
int n;
cin >> n;
MP[0] = 0;
ll r = -1, cur = 0, ans = 0;
for (int i = 1; i <= n; ++i) {
ll x; cin >> x;
cur += x;
if (MP.count(cur)) r = max(r, MP[cur]);
cout << MP[cur] << " = Mp[cur]" << endl;
cout << cur << "= cur " << endl;
cout << r + 1 << "= r + 1" << endl;
ans += r + 1;
MP[cur] = i;
cout << ans << " = ans" << endl;
}
ans = (n + 1ll) * n / 2 - ans;
cout << ans;
return 0;
}
D. Challenges in school №41
有一个n个箭头箭头序列,只能是L(左箭头)或者R(右箭头),每次操作可以选一对相邻的相对的箭头变成相背的箭头。每秒操作至少1次,求能够恰好k秒把整个箭头序列变成没有任何相对的箭头。
那么最后的序列肯定是LLLL…LLRRR…R这样,那么可以暴力算出每一轮能移多少并且至少移几轮。因为n只有3000,最坏情况下o(n²),满足条件。
当出现RL的时候就把R的下标保存。当RLL的时候要移俩轮,所以每次有RL存在,i++。
那么假设算出x轮,一共需要移y次。那么存在有解的情况的一定是x <= k && k <= y的。然后去贪心分配轮的次数,实现具体看代码。
#include
using namespace std;
vector<vector<int> >ans;
int a[3050];
char c;
int main(){
int n,k,sum=0;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>c;
a[i]=(c=='R');//转换为01串,左为0,右为1.
}
while(1){
vector<int>now;
for(int i=1;i<n;i++)
if(a[i]&&!a[i+1]) now.push_back(i),swap(a[i],a[i+1]),i++;
if(now.empty()) break;
sum+=now.size();
ans.push_back(now);
}
if(ans.size()>k||sum<k) puts("-1");
else {
int re=k-ans.size();//re(remain)需要填充的轮次
for(auto now:ans){
while(now.size()>1&&re>0){
printf("1 %d\n",now.back());
now.pop_back();
re--;
}
printf("%d ",now.size());
for(auto i:now) printf("%d ",i);
puts("");
}
}
return 0;
}
F. Kate and imperfection
题目大意:就是给你1到n个数选出2n个数,组成2n个大小为2~n的集合始得任意两个数的gcd的最大值最小
很明显我们先把所有的质数加入集合然后把2的倍数等等质数的倍数加入集合,单这个数加入的时候,这个数最大的因数就已经在集合里面,所以我们只要求出一个数最大的因数再排序即可
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define f first
#define s second
using namespace std;
const int N = 3e3 + 10, eps = 1e-10;
typedef long long ll;
typedef unsigned long long ULL;
int a[N], b[N];
char s[N];
int main()
{
IOS;
int n, m;
cin >> n;
vector<int> ans(n + 1, 1);
for (int i = 2; i <= n; ++i) {
for (int j = i + i; j <= n; j += i) {
ans[j] = i;
}
}
sort(ans.begin(), ans.end());
for (int i = 2; i <= n; ++i) cout << ans[i] << ' ';
return 0;
}