A: 错一位输出
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 998244353;
const int N = 2e5+10;
signed main(){
// IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int n; cin>>n;
cout<<n<<" ";
for(int i=1;i<n;i++) cout<<i<<" ";
cout<<endl;
}
return 0;
}
B:
排序,枚举
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 998244353;
const int N = 2e5+10;
struct Node{
int a,id;
bool operator <(const Node &T)const{
return a < T.a;
}
}node[N];
signed main(){
// IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
map<int,int> mp;
int n; cin>>n;
for(int i=0;i<n;i++){
int a; cin>>a;
node[i] = {a,i+1};
mp[a] ++;
}
sort(node,node+n);
int t = -1;
for(int i=0;i<n && t == -1;i++){
if(mp[node[i].a] == 1){
t = node[i].id;
break;
}
}
cout<<t<<endl;
}
return 0;
}
C:
把每个值对应的位置放到一堆,去计算这些点间有多少个区间(取最小值),注意左右边界的情况。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 998244353;
const int N = 2e5+10;
int a[N];
vector<int> ve[N];
signed main(){
// IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int n,cnt = 0; cin>>n;
for(int i=0;i<n;i++) cin>>a[i],ve[i+1].clear();
ve[a[0]].push_back(0);
for(int i=1;i<n;i++){
if(a[i] != a[i-1]){
ve[a[i]].push_back(i);
cnt = i;
}
}
int mi = INF,res = 0;
for(int i=1;i<=n;i++){
if((int)ve[i].size()){
res = (int)ve[i].size() - 1;
if(ve[i][0] != 0) res ++;
if(ve[i][(int)ve[i].size()-1] != cnt) res ++;
mi = min(res,mi);
}
}
// cout<<"cnt :"<<cnt<<endl;
cout<<mi<<endl;
}
return 0;
}
D:
用唯一分解定律分解出来,之后取出次数最大的,留一个全部输出,再输出剩下之积。
可以知道这样取是保证个数最多的。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 998244353;
const int N = 2e5+10;
int p[N],c[N];
signed main(){
// IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
int n; cin>>n;
memset(p,0,sizeof(p));
memset(c,0,sizeof(c));
int cnt = 0,ma = -INF,t = 0;
for(int i=2;i<=n/i;i++){
if(n % i == 0){
p[++cnt] = i;
while(n % i == 0) c[cnt] ++,n /= i;
if(c[cnt] > ma){
ma = c[cnt];
t = i;
}
}
}
if(n > 1) p[++cnt] = n,c[cnt] = 1;
if(c[cnt] > ma){
ma = c[cnt];
t = n;
}
int res = 1;
cout<<ma<<endl;
if(ma == 1){
for(int i=1;i<=cnt;i++){
while(c[i] --) res *= p[i];
}
}
else{
for(int i=1;i<=cnt;i++){
if(t == p[i]) c[i] = 1;
while(c[i] --) res *= p[i];
}
while(ma-- > 1) cout<<t<<" ";
}
cout<<res<<endl;
}
return 0;
}
E:
提上的信息可以知道,n个点n-1条边是一棵数,n个点n条边是有一个环,然后环上的各个点作为根节点,构成各自的树。
对于不同树上的点,可以有两条路径。对于同一棵树上的点,只有一条。
(先不考虑同一棵树)总共的路径就有n*(n-1)/2 * 2 = n * (n-1) (n为总节点数)
之后再减去同一棵树上的路径就行了。
对于同一棵树上的路径为(m-1)*m/2 (m为节点数)
这样,把每棵数的节点维护到环上对应的点,最后去遍历环上的点,就好计算。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 998244353;
const int N = 4e5+10;
int ne[N],h[N],e[N],idx=1;
int d[N],si[N],n;
bool vis[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void top_sort(){
queue<int> qe;
for(int i=1;i<=n;i++){
if(d[i] == 1){
qe.push(i);
vis[i] = true;
}
}
int res = n*(n-1);
while(!qe.empty()){
int t = qe.front();qe.pop();
for(int i=h[t];i;i=ne[i]){
int j = e[i];
if(--d[j] == 1) {
vis[j] = true;
qe.push(j);
}
si[j] += si[t];
}
}
// 遍历环上的点
for(int i=1;i<=n;i++){
if(!vis[i]) res -= si[i]*(si[i]-1)/2;
}
cout<<res<<endl;
}
signed main(){
IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int tt; cin>>tt;
while(tt --){
idx = 1;
cin>>n;
for(int i=1;i<=n;i++){
si[i] = 1; vis[i] = false;
h[i] = h[i+n] = 0;
d[i] = 0;
}
for(int i=0;i<n;i++){
int a,b; cin>>a>>b;
add(a,b); add(b,a);
d[b]++,d[a]++;
}
top_sort();
}
return 0;
}
F:
假设固定好左端,即l,则r我们可以分出下列几种情况。
if( max(1,l-1) != min(l,r) )
此时 if( max(1,l-1) > min(l,r) ) 只有把r往左移,才可能使得min(l,r)增大。
否则往右移
else
if( min(l,r) == max(r+1,n)) 找到一个合法方案
else if( min(l,r) < max(r+1,n)) 此时只有将r往左移动,才可能使min(l,r)变大,或往右max(r+1,n)才减小。
而左边的两个区间都已经确定好了,r往左移只会让左边的区间不相等且只会使右边区间增大,故只能往右移。
否则往左移
所以我们可以遍历固定l,二分r,找到了一个满足条件就输出。
对于区间最值,用ST表。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int mod = 998244353;
const int N = 2e5+10;
int dpmax[N][50],dpmin[N][50];
int H[N],a[N],n;
bool plas;
void ST_prework(){
int t = H[n] + 1;
for(int i=1;i<=n;i++) dpmax[i][0] = dpmin[i][0] = a[i];
for(int j=1;j<t;j++)
for(int i=1;i<=n-(1<<j)+1;i++){
dpmax[i][j] = max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
dpmin[i][j] = min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]);
}
}
int ST_askmax(int l,int r){
int k = H[(r - l + 1)];
return max(dpmax[l][k],dpmax[r-(1<<k)+1][k]);
}
int ST_askmin(int l,int r){
int k = H[(r - l + 1)];
return min(dpmin[l][k],dpmin[r-(1<<k)+1][k]);
}
bool check(int l,int r){
if(ST_askmin(l,r) != ST_askmax(1,l-1)){
return ST_askmin(l,r) > ST_askmax(1,l-1);
}else{
if(ST_askmin(l,r) == ST_askmax(r+1,n)) plas = true;
return ST_askmin(l,r) < ST_askmax(r+1,n);
}
}
signed main(){
IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
for(int i=1;i<N;i++) H[i] = log(i)/log(2);
int tt; cin>>tt;
while(tt --){
cin>>n;
plas = false;
for(int i=1;i<=n;i++) cin>>a[i];
ST_prework();
for(int i=2;i<=n&&!plas;i++){
int l = i,r = n-1;
while(l <= r){
int mid = (l + r) >>1;
if(mid >= n) break;
if(check(i,mid)) l = mid + 1;
else r = mid - 1;
if(plas){
cout<<"YES"<<endl;
cout<<i-1<<" "<<mid-i+1<<" "<<n-mid<<endl;
break;
}
}
}
if(!plas) cout<<"NO"<<endl;
}
return 0;
}