A:
特判情况,当n是<=k 的时候,都可以把让B为0点,A为n点。
否则:
当k时奇数的时候,AB,OB的距离差会构成全为奇数的长度。
反之为偶数。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<iostream>
#include<algorithm>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 9901;
const int N = 1010;
signed main(){
IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int n,k; cin>>n>>k;
if(n <= k) cout<<k-n<<endl;
else{
if(k%2){
if(n%2) cout<<0<<endl;
else cout<<1<<endl;
}else{
if(n%2 == 0) cout<<0<<endl;
else cout<<1<<endl;
}
}
}
return 0;
}
B:
a里面当2对应b里面1是会增加,当b里面2对应a里面1会减少。其他情况都为0.
所以我们只需要计算
a里面有多少2对应1 ,2多了和b里面2抵消。
b里面有多少2对应1.
代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<iostream>
#include<algorithm>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 9901;
const int N = 1010;
signed main(){
IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int a,b,c,a1,b1,c1; cin>>a>>b>>c>>a1>>b1>>c1;
int sum = 2*min(c,b1)-2*min(b,max(0ll,c1-a-max(0ll,c-b1)));
cout<<sum<<endl;
}
return 0;
}
C:
当某个数能被min整除时,说明它可以与min交换,那么我们可以利用这一点,把所有的能和min交换的数都交换。
我们只需判断当一个数不能整除min时,它若不处于本该处于的位置,则得不到合法序列。若所有这些情况都满足,则剩余的每一个位置,都可以通过与min交换得到合法序列。
代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<iostream>
#include<algorithm>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 9901;
const int N = 100010;
int a[N],b[N];
signed main(){
// IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int n,mi = INF; cin>>n;
for(int i=0;i<n;i++){
cin>>a[i],b[i] = a[i];
mi = min(mi,a[i]);
}
bool plas = true;
sort(b,b+n);
for(int i=0;i<n;i++){
if(a[i] % mi != 0 && a[i] != b[i]){
plas = false;
break;
}
}
cout<<(plas?"YES":"NO")<<endl;
}
return 0;
}
D:
此题贪心一下,想得到最大值,必然让走过最多次数的边的权值最大。
走过边的次数为,那条边左端点子树的数量乘右端点子树的数量(包括端点)。
这里可以用dfs的方法求出来。最后p和求出来的次数一一对应就可以了。
注意: 题上并没有说m<n.所以会分两种情况处理p数组,一种是让某些p为1.
种是让p等于它后面几个的连乘。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 200010;
int e[N],ne[N],h[N],idx=1;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int si[N],cnt,p[N],a[N],n,m;
int dfs(int u,int fa){
si[u] = 1;
for(int i=h[u];i;i=ne[i]){
int j = e[i];
if(j == fa) continue;
si[u] += dfs(j,u);
a[++cnt] = si[j] * (n-si[j]);
}
return si[u];
}
void init(){
memset(h,0,sizeof(h));
idx = 1;
cnt = 0;
}
signed main(){
// IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
init();
cin>>n;
for(int i=0;i<n-1;i++){
int a,b; cin>>a>>b;
add(a,b);add(b,a);
}
dfs(1,0);
cin>>m;
for(int i=1;i<=m;i++) cin>>p[i];
for(int i=m+1;i<=n-1;i++) p[i] = 1;//p处理,下面第一个sort也与这个有关
sort(p+1,p+max(m+1,n)); sort(a+1,a+cnt+1);
while(m-- > cnt) p[m] = (p[m] * p[m+1]) % mod;//p处理
int sum = 0;
for(int i=1;i<=cnt;i++)
sum = (sum + (p[i] * a[i])%mod) % mod;
cout<<sum<<endl;
}
return 0;
}