B
题目大意
给定一个数列,问整个区间和以及部分区间和哪个大。
整个区间和小于部分和就说明,肯定另一部分区间加起来和小于0,给贡献拉后腿,所以我们可以从判断从左边开始累加还有右边开始累加的和有小于0的直接就是整体输给部分
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; typedef long long ll; int n,m,a[maxn],T; char ch[maxn]; vector<int>v; ll l,r,maxx,sum,res,vis; int minn; int main() { scanf("%d",&T); while(T--){ vis=sum=res=0; maxx=-0x3f3f3f3f; minn=0x3f3f3f3f; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum+=a[i]; } for(int i=1;i<=n;i++){ sum-=a[i]; res+=a[i]; if(sum<=0&&i!=n) {vis=1;break;} if(res<=0){vis=1;break;} } // printf("^%lld %lld ",sum,maxx); if(vis==0) puts("YES"); else puts("NO"); } }
C. Fadi and LCM (CF 1285 C)
题目大意
给定xx,找出一对a,ba,b使得lcm(a,b)=x且max(a,b)最小。
lcm(a,b)=a*b/gcd(a,b)=x;
可以直接令gcd(a,b)=1,然后从小枚举a,算出b,这样的话b就是从大到小,a从小到大不断向中间靠拢,可得出最优解
#include<bits/stdc++.h> using namespace std; const long long maxn=LLONG_MAX; typedef long long ll; int n,m,T; vector<int>v; ll l,r,maxx,sum,res,vis; int minn; ll gcd(ll m, ll n) { return m % n == 0 ? n : gcd(n, m % n); } int main() { ll x; while (~scanf("%lld",&x)) { pair<ll, ll > pr; ll i, m; m = sqrt(x); ll a, b; pr.first = pr.second =maxn; for (i=1;i<=m;i++) { a=i; if (x%a==0) { b=x/a; ll g=gcd(a, b); if (b<pr.second&&(g==1||a==1)) { pr.first=a; pr.second=b; } } } cout << pr.first << ' ' << pr.second << endl; } return 0; }
题目大意:给一组数,找一个x使的x和所有给的数的异或值的最大值max最小,求这个max
解题思路:从每个数的二进制第30位开始到第1位,如果这一位对于所有的数来说都是0或者都是1,那么max在这一位就可以取0(因为要你的max最小,那你x可以去和这个位置一样的0/1,max这个位置肯定就是一个0,),如果这一位既有0又有1,那么这一位一定是1,无论你x取1/0,都得和其中一个异或出一个1出来,因为他是最大值max。对于这种情况,x的取值就有两种,对于x取1和x取0,那我们问题就是我们x取1还是0来让这个max最小,所以我们要递归下去来取最小,我们用vect容器v1表示存起来这个位置是1的数字,v0表示这个位置是0的数字。然后开始下面进行判断,如果v1里面没有数字,说明都在v0里,也就是该位置全是0,那么max这位置是0,直接递归下去判断下一个位置,v0也是如此。但是当出现v1,v0都非空,那我们可以进行我们就要兵分两路了,因为对于对应的x不一样了,min(dfs(v1),dfs(v0)
表示后面的值得取小,所以可以调用自己。
v1的x对应0,v0的x对应1,然后取最小值,。因为该位置必取1,所以还得加上1<<bit;
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <functional> #include <map> #include <set> #include <stack> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; const int M = 1e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 998244353; vector<ll> v; ll dfs(vector<ll> &v, int bit) { vector<ll> v0, v1; if (bit < 0 || v.size() == 0) return 0; for (ll &j : v) { if ((j >> bit) & 1) v1.push_back(j); else v0.push_back(j); } if (v1.size() == 0) return dfs(v0, bit - 1); if (v0.size() == 0) return dfs(v1, bit - 1); return min(dfs(v0, bit - 1), dfs(v1, bit - 1)) + (1<<bit); } int main() { int n; v.clear(); scanf("%d", &n); for (int i = 0; i < n; i++) { ll x; scanf("%lld", &x); v.push_back(x); } ll ans = dfs(v, 30); printf("%lld ", ans); return 0; }