A Even Substrings
求偶数。
只要保证个位能够被2整除就是偶数。所以从后向前遍历。
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
void cfA(){
int n; cin>>n;
string str; cin>>str;
int ans=0;
for(int i=n-1;i>=0;i--){
if((str[i]-48)%2==0) ans+=i+1;
}
cout<<ans<<endl;
}
int main(){
cfA();
return 0;
}
B Chocolates
题目关键是 x j < x i x_j<x_i xj<xi,其中 j < i j<i j<i,从中需要得出一个结论,就是最后一个元素不管是多少都必须要选。 因为它必须要比前面的元素大,而且因为它最后面,需要自身尽可能的大,所以最后一个元素一定选它自身的值。
这样从后先前搜索即可。
此题答案需要开 long long
#include<iostream>
#include<cstdlib>
using namespace std;
int inte[200010];
void cfB(){
int n; cin>>n;
for(int i=0;i<n;i++) cin>>inte[i];
//the last one must choose
long long ans=inte[n-1];
int pre=inte[n-1]; //the previous
for(int i=n-2;i>=0;i--){
if(inte[i]<pre){ //the next is inte[i]
ans+=inte[i];
pre=inte[i];
}else{
pre-=1;
if(pre<0) pre=0; //it is positive
ans+=pre; //the previous -1
}
}
cout<<ans<<endl;
}
int main(){
cfB();
return 0;
}
C Edgy Trees
并查集
并查集模板
//union
void init(int n){
for(int i=0;i<n;i++){
par[i]=i; //each is the root of itself
rank1[i]=0;
}
}
int find(int x){
if(par[x]==x) return x;
else{
return par[x]=find(par[x]); //at the time of searching,short the way to root
}
}
void merge(int x,int y){
int xx=find(x);
int yy=find(y);
if(xx==yy) return ;
if(rank1[xx]<rank1[yy]){
par[xx]=yy;
}else{
par[yy]=xx;
if(rank1[xx]==rank1[yy]) rank1[xx]++;
}
}
快速幂
快速幂就是为了快速求幂,
如: x y x^y xy ,按照朴素算法就是把x连乘y次,
普通做法时间复杂度是 O ( y ) O(y) O(y) 即 O ( n ) O(n) O(n),
快速幂时间复杂度为 O ( l o g n ) O(logn) O(logn)
快速幂模板:
long long powx(int x,int y){
long long ans=1;
long long base=x;
while(y!=0){ //when all the bit lose,y==0
if(y&1!=0){ //the lowest of y is 1
ans*=base;
}
base*=base;
y>>=1; //move one bit to right
}
}
题解博客
在长度为
k
k
k的序列里,由于每个位置有
n
n
n种可能,所以总的可能数为
n
k
n^k
nk用总的可能数减去仅经过红边的序列数即可。
由于仅经过红边说明在这些节点在同一个连通区域,并且相互之间只有红边相连。
( n k − ∑ i = 1 n u m s u m [ i ] k + m o d ) % m o d (n^k− \sum_{i=1}^{num}sum[i]^k+mod)\%mod (nk−i=1∑numsum[i]k+mod)%mod
#include<iostream>
#include<vector>
#include<cstdlib>
using namespace std;
int par[100010];
int rank1[100010];
int sum[100010];
long long mod_number=1e9+7;
long long powx(int x,int y){
long long ans=1;
long long base=x;
while(y!=0){ //when all the bit lose,y==0
if(y&1!=0){ //the lowest of y is 1
ans*=base; ans%=mod_number;
}
base*=base; base%=mod_number;
y>>=1; //move one bit to right
}
return ans;
}
//union
void init(int n){
for(int i=0;i<=n;i++){
par[i]=i; //each is the root of itself
rank1[i]=0;
sum[i]=1;
}
}
int find(int x){
if(par[x]==x) return x;
else{
return par[x]=find(par[x]); //at the time of searching,short the way to root
}
}
void merge(int x,int y){
int xx=find(x);
int yy=find(y);
if(xx==yy) return;
if(rank1[xx]<rank1[yy]){
par[xx]=yy;
sum[yy]+=sum[xx]; //the sum number of the union
}else{
par[yy]=xx;
if(rank1[xx]==rank1[yy]) rank1[xx]++;
sum[xx]+=sum[yy]; //the sum number of the union
}
}
void cfC(){
int n,k; cin>>n>>k;
init(n);
for(int i=1;i<=n-1;i++){
int x1,y1,w; cin>>x1>>y1>>w;
if(w==0){
merge(x1,y1); //add to graph
}
}
//check all the gather
long long summ=0;
for(int i=1;i<=n;i++){
if(par[i]==i){
summ+=powx(sum[i],k);
summ%=mod_number;
}
}
cout<<(powx(n,k)-summ+mod_number)%mod_number<<endl;
}
int main(){
cfC();
// system("pause");
return 0;
}