C
輸入三角形的一條邊,輸出另外兩條可以和他組成一個直角三角形的整數邊。
以前似乎做過,但是忘記了可以的公式,但時間範圍很長可以直接遞歸
公式:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<deque>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define MOD 1000000007
#define N 100005
using namespace std;
ll y,z;
void work(ll x){
if(x==4){
y=3;
z=5;
}
else if (x%2){
y=(x*x)/2;
z=(x*x)/2+1;
}
else{
work(x/2);
y*=2;
z*=2;
}
return;
}
int main(){
ll x;
scanf("%lld",&x);
if (x==1||x==2) printf("-1");
else {
work(x);
printf("%lld %lld",y,z);
}
}
D
BITSET的一些妙用
剛開始想用線段樹強解,發現dfs更新很麻煩,在網上看了一下大家的代碼,用bitset就很方便了,因爲只有0/1的狀態,
用樹狀結構存儲往回跳的步驟,最後dfs搜索即可,ans即時更新。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<deque>
#include<bitset>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define MOD 1000000007
#define N 100005
using namespace std;
bitset<1005>b[1005];
bitset<1005>c;
int n,m,Q,p[N],tot=0,head[N];
struct edge{
int v, next;
}e[N*2];
struct op{
int x,i,j;
}q[N];
void addedge(int u, int v){
e[++tot]=(edge){v,head[u]};
head[u]=tot;
}
void dfs(int now, int ans){
if (now==Q+1) return;
if (q[now].x==1){
int tmp=b[q[now].i][q[now].j];
if (!tmp) b[q[now].i][q[now].j]=1, ans++;
p[now]=ans;
for (int i=head[now];i;i=e[i].next){
dfs(e[i].v,ans);
}
if (!tmp) b[q[now].i].reset(q[now].j),ans--;
}
else if (q[now].x==2){
int tmp=b[q[now].i][q[now].j];
if (tmp) b[q[now].i][q[now].j]=0, ans--;
p[now]=ans;
for (int i=head[now];i;i=e[i].next){
dfs(e[i].v,ans);
}
if (tmp) b[q[now].i][q[now].j]=1,ans++;
}
else if (q[now].x==3){
int cnt=b[q[now].i].count();
b[q[now].i]^=c;
ans=ans-cnt+(m-cnt);
p[now]=ans;
for (int i=head[now];i;i=e[i].next){
dfs(e[i].v,ans);
}
b[q[now].i]^=c;
ans=ans-(m-cnt)+cnt;
}
else if (q[now].x==4){
p[now]=ans;
for (int i=head[now];i;i=e[i].next){
dfs(e[i].v,ans);
}
}
}
int main(){
int k;
scanf("%d%d%d",&n,&m,&Q);
go(i,1,m) c[i]=1;
q[0].x=4;
go(i,1,Q){
scanf("%d",&q[i].x);
if (q[i].x==1||q[i].x==2)scanf("%d%d",&q[i].i,&q[i].j);
else if (q[i].x==3) scanf("%d",&q[i].i);
if (q[i].x==4){
scanf("%d",&k);
addedge(k,i);
}
else addedge(i-1,i);
}
dfs(0,0);
go(i,1,Q){
printf("%d\n",p[i]);
}
}
E
比賽的時候並沒有思路,感覺二維線段樹肯定會超時,然後滾去上課。
然後查題解發現並不會,然後看到一個題解是用主席樹寫的,(於是學習了一下主席樹,創新性的給自己寫了一個非遞歸模板,這題根本用不了,只好重新寫了一個遞歸的)。
題目的思路主要是:
1.先把每個garland的點都讀進一個vector保存,sort成以x爲第一關鍵字的順序序列
2.離線處理詢問,將詢問按順序讀入,對於每個詢問,記錄當前garland開關的狀態(處理方式是記錄每個garland會對哪些詢問做出貢獻,而非直接記錄狀態)
3.利用主席樹對於每個garland(的y)建立主席樹,然後利用主席樹的結構限制x的範圍,達到二維的目的(666)
以及has[i].size()出現了一些bug,size的形式是unsigned int,-1之後就是無窮大了,注意。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<deque>
#define N 2005
#define ll long long
#define go(i,a,b) for (ll i=a;i<=b;i++)
using namespace std;
struct place{
int x,y;
ll w;
bool operator< (const place b){
if (x==b.x) return y<b.y;
return x<b.x;
}
};
struct node{
int ls,rs;
ll sum;
}t[N*20];
struct query{
int x1,y1,x2,y2,typ,i;
}q[1000005];
int top[N];
bool now[N];
vector<place>gar[N];
vector<int>has[N];
char s[20];
ll cnt,ans[1000005];
int updata(int pre, int l, int r, int pos, int c){
ll rt=++cnt;
t[rt]=t[pre];
t[rt].sum+=c;
if (l==r) return rt;
int m=(l+r)/2;
if (pos<=m) t[rt].ls=updata(t[pre].ls,l,m,pos,c);
else t[rt].rs=updata(t[pre].rs,m+1,r,pos,c);
return rt;
}
ll query(int rt1, int rt2, int l, int r, int left, int right){
if (l>right||r<left) return 0;
if (left<=l&&r<=right){
return t[rt2].sum-t[rt1].sum;
}
int m=(l+r)/2;
return query(t[rt1].ls,t[rt2].ls,l,m,left,right)+
query(t[rt1].rs,t[rt2].rs,m+1,r,left,right);
}
int main(){
int n,m,k,len,x,y,Q;
ll w;
while (scanf("%d%d%d",&n,&m,&k)!=EOF){
go(i,1,k){
now[i]=true;
scanf("%d",&len);
go(j,1,len){
scanf("%d%d%lld",&x,&y,&w);
gar[i].push_back((place){x,y,w});
}
sort(gar[i].begin(),gar[i].end());
}
scanf("%d",&Q);
go(i,1,Q){
scanf("%s",s);
if (s[0]=='S'){
scanf("%d",&q[i].i);
q[i].typ=1;
now[q[i].i]^=1;
}
else{
//cout<<"!"<<endl;
scanf("%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2);
q[i].typ=2;
go(j,1,k){
if (now[j]) has[j].push_back(i);
}
}
}
go(i,1,k){
cnt=0;
go(j,0,gar[i].size()-1){
top[j+1]=updata(top[j],1,m,gar[i][j].y,gar[i][j].w);
}
//cout<<i<<endl;
for (int j=0;j<=has[i].size()-1;j++){
if (has[i].size()==0) break;
int tmp=has[i][j];
int x1=q[tmp].x1,y1=q[tmp].y1,x2=q[tmp].x2,y2=q[tmp].y2;
place temp=(place){x2,m+1};
int pos=lower_bound(gar[i].begin(),gar[i].end(),temp)-gar[i].begin();
if (pos) ans[tmp]+=query(0,top[pos],1,m,y1,y2);
temp=(place){x1,0};
pos=lower_bound(gar[i].begin(),gar[i].end(),temp)-gar[i].begin();
if (pos) ans[tmp]-=query(0,top[pos],1,m,y1,y2);
}
}
go(i,1,Q){
if (q[i].typ==2) printf("%lld\n",ans[i]);
}
}
return 0;
}